Sti3bas / laravel-scout-array-driver

Array driver for Laravel Scout
MIT License
89 stars 8 forks source link

Add an ability to fake search response data #22

Open Sti3bas opened 1 month ago

Sti3bas commented 1 month ago

It is still work in progress and there might be API changes.

Usage:

Search::fakeResponseData([
   'foo' => 'bar'
])->query('test');

$search = User::search('test')->raw();

$this->assertEquals('bar', $search['foo']);

It is possible to provide filters (supports all Laravel\Scout\Builder methods) to fake response data for a specific search:

Search::fakeResponseData([
   'foo' => 'bar'
])
   ->within('users')
   ->where('foo', 'bar'),
   ->whereIn('foo', ['bar', 'baz'])
   ->whereNotIn('foo', ['foo', 'bar'])
   ->withTrashed()
   ->onlyTrashed()
   ->take(50)
   ->orderBy('test', 'desc')
   ->latest('created_at')
   ->oldest('updated_at')
   ->options(['foo' => 'bar']);

TODO:

christian-nielsen commented 1 month ago

lets say you have some that fetches from two diffrent scout models? Would you be able to fake both responses. So you would get one fake response for the User and the another for the company?

Search::fakeResponseData([ 'foo' => 'bar' ])->model(User::class);

Search::fakeResponseData([ 'foo' => 'abc' ])->model(Company::class);

// code in some class User::search(...)->raw() Company::search(...)->raw()

Sti3bas commented 1 month ago

@christian-nielsen yes, we have within method for that:

Search::fakeResponseData([
   'foo' => 'bar'
])->within('users');

Search::fakeResponseData([
   'foo' => 'baz'
])->within('posts'); // or $post->searchableAs()

If you don't call within then I think it would be nice if response would be faked for all indexes by default.

I'm not sure if it would be possible to use User::class as a value since index value is returned from searchableAs method so we need to have a model instance for that. Maybe it would be OK to use (new $className)->searchableAs() inside within method.

christian-nielsen commented 1 month ago

What about also allowing class model name:

Search::fakeResponseData([
   'foo' => 'baz'
])->within(Post::class);

if you give it a class model name, it will do this underlaying: (new $className)->searchableAs()

Sti3bas commented 1 month ago

@christian-nielsen it might be fine for models which returns a static value, but in theory it might depend on some database fields. I think it would be nice to support all combinations: string, model instance, model class name.