toBeInstanceOf(Crud::class); }); it('can be instantiated via from method', function () { // GIVEN $modelClass = ModelClass::class; // WHEN $crud = Crud::from( $modelClass, [], [], [] ); // THEN expect($crud)->toBeInstanceOf(Crud::class); }); it('cannot be instantiated with invalid model class', function (string $modelClass) { // GIVEN /** @var class-string $modelClass */ $modelClassValue = $modelClass; // WHEN $action = fn () => new Crud( $modelClassValue, [], [], [] ); // THEN expect($action)->toThrow(SitemapException::class); })->with([ 'empty string' => '', 'non-existent class' => 'App\\NonExistentModel', 'class not extending Model' => SitemapException::class, 'class does not implements Sitemapable' => get_class(new class () extends Model { }), 'abstract class' => AbstractModelClass::class, ]); it('can be instantiated with relations filters', function () { // GIVEN $modelClass = ModelClass::class; $relationsFilters = [ 'relation1' => 'filter1', 'relation2' => fn (Builder $q) => $q->where('status', true), ]; // WHEN $crud = new Crud( $modelClass, $relationsFilters, [], [] ); // THEN expect($crud)->toBeInstanceOf(Crud::class); }); it('cannot be instantiated with invalid relations filters', function (array $relationsFilters) { // GIVEN $modelClass = ModelClass::class; // WHEN $action = fn () => new Crud( $modelClass, // @phpstan-ignore argument.type $relationsFilters, [], [] ); // THEN expect($action)->toThrow(SitemapException::class); })->with([ 'empty relation name' => [['' => 'filter1']], 'whitespace relation name' => [[' ' => 'filter1']], 'numeric relation index' => [['filter1']], 'empty string constraint' => [['relation1' => '']], 'empty array constraint' => [['relation1' => []]], 'integer constraint' => [['relation1' => 2]], ]); it('can be instantiated with models filters', function () { // GIVEN $modelClass = ModelClass::class; $modelsFilters = [ 'filter1' => ['published', '=', true], ]; // WHEN $crud = new Crud( $modelClass, [], $modelsFilters, [] ); // THEN expect($crud)->toBeInstanceOf(Crud::class); }); it('cannot be instantiated with invalid models filters', function (array $modelsFilters) { // GIVEN $modelClass = ModelClass::class; // WHEN $action = fn () => new Crud( $modelClass, [], // @phpstan-ignore argument.type $modelsFilters, [] ); // THEN expect($action)->toThrow(SitemapException::class); })->with([ 'empty filter array' => [[[]]], 'empty filter string' => [['']], 'whitespace filter' => [[' ']], 'integer filter' => [[123]], 'boolean filter' => [[true]], ]); it('can be instantiated with allow null relations', function () { // GIVEN $modelClass = ModelClass::class; // WHEN $crud = new Crud( $modelClass, [], [], ['relation1', 'relation2'] ); // THEN expect($crud)->toBeInstanceOf(Crud::class); }); it('cannot be instantiated with invalid allow null relations', function (array $allowNullRelations) { // GIVEN $modelClass = ModelClass::class; // WHEN $action = fn () => new Crud( $modelClass, [], [], // @phpstan-ignore argument.type $allowNullRelations ); // THEN expect($action)->toThrow(SitemapException::class); })->with([ 'empty string item' => [['']], 'whitespace item' => [[' ']], 'integer item' => [[123]], 'boolean item' => [[true]], ]); it('can be instantiated with all filters', function () { // GIVEN $modelClass = ModelClass::class; $relationsFilters = [ 'relation1' => 'filter1', 'relation2' => fn (Builder $q) => $q->where('status', true), ]; $modelsFilters = [ 'filter1' => ['published', '=', true], ]; // WHEN $crud = new Crud( $modelClass, $relationsFilters, $modelsFilters, ['relation1', 'relation2'] ); // THEN expect($crud)->toBeInstanceOf(Crud::class); }); it('can be instantiated with permutations of valid filters', function (array $relationFilters, array $modelFilters, array $allowNullRelations) { // GIVEN $modelClass = ModelClass::class; // WHEN $crud = new Crud( $modelClass, // @phpstan-ignore argument.type $relationFilters, // @phpstan-ignore argument.type $modelFilters, // @phpstan-ignore argument.type $allowNullRelations ); // THEN expect($crud)->toBeInstanceOf(Crud::class) ->and($crud->relationFilters)->toBe($relationFilters) ->and($crud->modelFilters)->toBe($modelFilters) ->and($crud->allowNullRelations)->toBe($allowNullRelations); })->with( [ 'no relation filters' => [[]], 'string relation filter' => [['relation1' => 'filter1']], ], [ 'no model filters' => [[]], 'array model filter' => [[['published', '=', true]]], ], [ 'no allow null' => [[]], 'single allow null' => [['relation1']], ] ); });