Skip to content

Commit b140c77

Browse files
committed
wip
1 parent 1e40549 commit b140c77

6 files changed

Lines changed: 158 additions & 29 deletions

File tree

docs/guide/testing.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,3 +279,13 @@ $this->sharpDashboard(MyDashboard::class)
279279
->post()
280280
->assertOk();
281281
```
282+
283+
## Global filters
284+
285+
If your app contains global filters, you should be able to test normally, but it will be set to its default value. If you need, you can set a specific value using `withGlobalFilter()`:
286+
287+
```php
288+
$this->withGlobalFilter(CompanyFilter::class, 'apple')
289+
->sharpList(Post::class)
290+
//...
291+
```

src/Filters/GlobalFilters/GlobalFilters.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,14 @@ public function toArray(): array
5353
}
5454

5555
public function isDeclared(string $key): bool
56+
{
57+
return $this->getDeclaredFilter($key) !== null;
58+
}
59+
60+
public function getDeclaredFilter(string $key): ?GlobalRequiredFilter
5661
{
5762
return collect(sharp()->config()->get('global_filters'))
58-
->contains(function (GlobalRequiredFilter $filter) use ($key) {
63+
->first(function (GlobalRequiredFilter $filter) use ($key) {
5964
$filter->buildFilterConfig();
6065

6166
if (class_exists($key)) {

src/Utils/Testing/EntityList/PendingEntityList.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,11 @@ public function sharpForm(string $entityClassNameOrKey, string|int $instanceId):
5151

5252
public function withFilter(string $filterKey, mixed $value): static
5353
{
54-
$key = $this->entityList->filterContainer()->findFilterHandler($filterKey)->getKey();
55-
$this->filterValues[$key] = $value;
54+
$filter = $this->entityList->filterContainer()->findFilterHandler($filterKey);
55+
56+
PHPUnit::assertNotNull($filter, sprintf('Unknown entity list filter [%s]', $filterKey));
57+
58+
$this->filterValues[$filter->getKey()] = $value;
5659

5760
return $this;
5861
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
namespace Code16\Sharp\Utils\Testing;
4+
5+
use Code16\Sharp\Filters\GlobalFilters\GlobalFilters;
6+
use Code16\Sharp\Filters\GlobalRequiredFilter;
7+
use Illuminate\Support\Facades\URL;
8+
use PHPUnit\Framework\Assert as PHPUnit;
9+
10+
/**
11+
* @internal
12+
*/
13+
trait HasGlobalFilters
14+
{
15+
private array $globalFilterValues = [];
16+
private ?string $globalFilterSegment = null;
17+
18+
public function withSharpGlobalFilter(string $globalFilterKeyOrClassName, mixed $value): static
19+
{
20+
$filter = app(GlobalFilters::class)->filterContainer()->findFilterHandler($globalFilterKeyOrClassName);
21+
22+
if (! $filter) {
23+
$declaredFilter = app(GlobalFilters::class)->getDeclaredFilter($globalFilterKeyOrClassName);
24+
PHPUnit::assertNotNull($declaredFilter, "Global filter [$globalFilterKeyOrClassName] is not declared.");
25+
PHPUnit::assertTrue($declaredFilter->authorize(), "Global filter [$globalFilterKeyOrClassName] is not authorized.");
26+
PHPUnit::assertNotEmpty($declaredFilter->values(), "Global filter [$globalFilterKeyOrClassName] has no values.");
27+
}
28+
29+
$this->globalFilterValues[$filter->getKey()] = $value;
30+
31+
$this->setGlobalFilterUrlDefault();
32+
33+
return $this;
34+
}
35+
36+
/**
37+
* @deprecated use withSharpGlobalFilter() instead
38+
*/
39+
public function withSharpGlobalFilterValues(array|string $globalFilterValues): static
40+
{
41+
$this->globalFilterSegment = collect((array) $globalFilterValues)
42+
->implode(GlobalFilters::$valuesUrlSeparator);
43+
44+
$this->setGlobalFilterUrlDefault();
45+
46+
return $this;
47+
}
48+
49+
/**
50+
* @internal
51+
*/
52+
public function setGlobalFilterUrlDefault(): static
53+
{
54+
if ($this->globalFilterSegment) {
55+
URL::defaults(['globalFilter' => $this->globalFilterSegment]);
56+
} else {
57+
$values = collect(app(GlobalFilters::class)->getFilters())
58+
->map(fn (GlobalRequiredFilter $globalFilter) => $this->globalFilterValues[$globalFilter->getKey()] ?? $globalFilter->defaultValue()
59+
)
60+
->implode(GlobalFilters::$valuesUrlSeparator);
61+
62+
URL::defaults(['globalFilter' => $values ?: GlobalFilters::$defaultKey]);
63+
}
64+
65+
return $this;
66+
}
67+
}

src/Utils/Testing/SharpAssertions.php

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,62 +3,58 @@
33
namespace Code16\Sharp\Utils\Testing;
44

55
use Closure;
6-
use Code16\Sharp\Filters\GlobalFilters\GlobalFilters;
76
use Code16\Sharp\Http\Context\SharpBreadcrumb;
87
use Code16\Sharp\Utils\Entities\SharpEntityManager;
98
use Code16\Sharp\Utils\Links\BreadcrumbBuilder;
109
use Code16\Sharp\Utils\Testing\Dashboard\PendingDashboard;
1110
use Code16\Sharp\Utils\Testing\EntityList\PendingEntityList;
1211
use Code16\Sharp\Utils\Testing\Form\PendingForm;
1312
use Code16\Sharp\Utils\Testing\Show\PendingShow;
14-
use Illuminate\Support\Facades\URL;
1513

1614
trait SharpAssertions
1715
{
1816
use GeneratesCurrentPageUrl;
17+
use HasGlobalFilters;
1918

2019
private BreadcrumbBuilder $breadcrumbBuilder;
21-
private ?string $globalFilter = null;
2220

2321
public function setUpSharpAssertions(): void
2422
{
25-
URL::defaults(['globalFilter' => $this->globalFilter ?: GlobalFilters::$defaultKey]);
23+
$this->setGlobalFilterUrlDefault();
2624
}
2725

2826
public function sharpList(string $entityClassNameOrKey): PendingEntityList
2927
{
28+
$this->setGlobalFilterUrlDefault();
29+
3030
return new PendingEntityList($this, $entityClassNameOrKey);
3131
}
3232

3333
public function sharpShow(string $entityClassNameOrKey, int|string|null $instanceId = null): PendingShow
3434
{
35+
$this->setGlobalFilterUrlDefault();
36+
3537
return new PendingShow($this, $entityClassNameOrKey, $instanceId);
3638
}
3739

3840
public function sharpForm(string $entityClassNameOrKey, int|string|null $instanceId = null): PendingForm
3941
{
42+
$this->setGlobalFilterUrlDefault();
43+
4044
return new PendingForm($this, $entityClassNameOrKey, $instanceId);
4145
}
4246

4347
public function sharpDashboard(string $entityClassNameOrKey): PendingDashboard
4448
{
45-
return new PendingDashboard($this, $entityClassNameOrKey);
46-
}
47-
48-
public function withSharpGlobalFilterValues(array|string $globalFilterValues): self
49-
{
50-
$this->globalFilter = collect((array) $globalFilterValues)
51-
->implode(GlobalFilters::$valuesUrlSeparator);
52-
53-
URL::defaults(['globalFilter' => $this->globalFilter ?: GlobalFilters::$defaultKey]);
49+
$this->setGlobalFilterUrlDefault();
5450

55-
return $this;
51+
return new PendingDashboard($this, $entityClassNameOrKey);
5652
}
5753

5854
/**
5955
* @deprecated use withSharpBreadcrumb() instead
6056
*/
61-
public function withSharpCurrentBreadcrumb(...$breadcrumb): self
57+
public function withSharpCurrentBreadcrumb(...$breadcrumb): static
6258
{
6359
$this->breadcrumbBuilder = new BreadcrumbBuilder();
6460

@@ -77,7 +73,7 @@ public function withSharpCurrentBreadcrumb(...$breadcrumb): self
7773
* @param (\Closure(BreadcrumbBuilder): BreadcrumbBuilder) $callback
7874
* @return $this
7975
*/
80-
public function withSharpBreadcrumb(Closure $callback): self
76+
public function withSharpBreadcrumb(Closure $callback): static
8177
{
8278
$this->breadcrumbBuilder = $callback(new BreadcrumbBuilder());
8379

@@ -92,7 +88,6 @@ public function deleteFromSharpShow(string $entityClassNameOrKey, mixed $instanc
9288
->delete(
9389
route(
9490
'code16.sharp.show.delete', [
95-
'globalFilter' => $this->globalFilter,
9691
'parentUri' => $this->breadcrumbBuilder($entityKey)->generateUri(),
9792
'entityKey' => $entityKey,
9893
'instanceId' => $instanceId,
@@ -114,7 +109,6 @@ public function deleteFromSharpList(string $entityClassNameOrKey, mixed $instanc
114109
)
115110
->delete(
116111
route('code16.sharp.api.list.delete', [
117-
'globalFilter' => $this->globalFilter,
118112
'entityKey' => $entityKey,
119113
'instanceId' => $instanceId,
120114
])
@@ -131,7 +125,6 @@ public function getSharpForm(string $entityClassNameOrKey, mixed $instanceId = n
131125
? route(
132126
'code16.sharp.form.edit',
133127
[
134-
'globalFilter' => $this->globalFilter,
135128
'parentUri' => $this->breadcrumbBuilder($entityKey)->generateUri(),
136129
'entityKey' => $entityKey,
137130
'instanceId' => $instanceId,
@@ -140,7 +133,6 @@ public function getSharpForm(string $entityClassNameOrKey, mixed $instanceId = n
140133
: route(
141134
'code16.sharp.form.create',
142135
[
143-
'globalFilter' => $this->globalFilter,
144136
'parentUri' => $this->breadcrumbBuilder($entityKey)->generateUri(),
145137
'entityKey' => $entityKey,
146138
]
@@ -157,7 +149,6 @@ public function getSharpSingleForm(string $entityClassNameOrKey)
157149
route(
158150
'code16.sharp.form.edit',
159151
[
160-
'globalFilter' => $this->globalFilter,
161152
'parentUri' => $this->breadcrumbBuilder($entityKey)->generateUri(),
162153
'entityKey' => $entityKey,
163154
]
@@ -173,7 +164,6 @@ public function updateSharpForm(string $entityClassNameOrKey, $instanceId, array
173164
->post(
174165
route(
175166
'code16.sharp.form.update', [
176-
'globalFilter' => $this->globalFilter,
177167
'parentUri' => $this->breadcrumbBuilder($entityKey)->generateUri(),
178168
'entityKey' => $entityKey,
179169
'instanceId' => $instanceId,
@@ -191,7 +181,6 @@ public function updateSharpSingleForm(string $entityClassNameOrKey, array $data)
191181
->post(
192182
route(
193183
'code16.sharp.form.update', [
194-
'globalFilter' => $this->globalFilter,
195184
'parentUri' => $this->breadcrumbBuilder($entityKey)->generateUri(),
196185
'entityKey' => $entityKey,
197186
]
@@ -209,7 +198,6 @@ public function getSharpShow(string $entityClassNameOrKey, $instanceId)
209198
route(
210199
'code16.sharp.show.show',
211200
[
212-
'globalFilter' => $this->globalFilter,
213201
'parentUri' => $this->breadcrumbBuilder($entityKey)->generateUri(),
214202
'entityKey' => $entityKey,
215203
'instanceId' => $instanceId,
@@ -227,7 +215,6 @@ public function storeSharpForm(string $entityClassNameOrKey, array $data)
227215
route(
228216
'code16.sharp.form.store',
229217
[
230-
'globalFilter' => $this->globalFilter,
231218
'parentUri' => $this->breadcrumbBuilder($entityKey)->generateUri(),
232219
'entityKey' => $entityKey,
233220
]
@@ -317,7 +304,7 @@ public function callSharpEntityCommandFromList(
317304
);
318305
}
319306

320-
public function loginAsSharpUser($user): self
307+
public function loginAsSharpUser($user): static
321308
{
322309
return $this->actingAs($user, sharp()->config()->get('auth.guard') ?: config('auth.defaults.guard'));
323310
}

tests/Http/SharpAssertionsHttpTest.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
use Code16\Sharp\Utils\Testing\SharpAssertions;
2525
use Illuminate\Http\UploadedFile;
2626
use Illuminate\Testing\Fluent\AssertableJson;
27+
use Illuminate\Testing\TestResponse;
2728

2829
pest()
2930
->use(ResetUrlDefaults::class)
@@ -794,3 +795,59 @@ public function execute(array $data = []): array
794795
->dashboardCommand('cmd-form')->getForm()->post(['action' => 'info'])
795796
->assertReturnsInfo('dashboard');
796797
});
798+
799+
it('set default global filter', function () {
800+
fakeGlobalFilter();
801+
802+
$this
803+
->sharpList(PersonEntity::class)
804+
->get()
805+
->assertOk()
806+
->tap(fn (TestResponse $response) => expect($response->baseRequest->route('globalFilter'))->toEqual('two')
807+
);
808+
809+
$this
810+
->sharpShow(PersonEntity::class, 1)
811+
->get()
812+
->assertOk()
813+
->tap(fn (TestResponse $response) => expect($response->baseRequest->route('globalFilter'))->toEqual('two')
814+
);
815+
816+
$this
817+
->sharpForm(PersonEntity::class)
818+
->create()
819+
->assertOk()
820+
->tap(fn (TestResponse $response) => expect($response->baseRequest->route('globalFilter'))->toEqual('two')
821+
);
822+
});
823+
824+
it('set specified global filter', function () {
825+
fakeGlobalFilter('test');
826+
827+
$this->withSharpGlobalFilter('test', 'one');
828+
829+
$this
830+
->sharpList(PersonEntity::class)
831+
->get()
832+
->assertOk()
833+
->tap(fn (TestResponse $response) => expect($response->baseRequest->route('globalFilter'))->toEqual('one')
834+
);
835+
836+
$this->withSharpGlobalFilter('test', 'two');
837+
838+
$this
839+
->sharpShow(PersonEntity::class, 1)
840+
->get()
841+
->assertOk()
842+
->tap(fn (TestResponse $response) => expect($response->baseRequest->route('globalFilter'))->toEqual('two')
843+
);
844+
845+
$this->withSharpGlobalFilter('test', 'one');
846+
847+
$this
848+
->sharpForm(PersonEntity::class)
849+
->create()
850+
->assertOk()
851+
->tap(fn (TestResponse $response) => expect($response->baseRequest->route('globalFilter'))->toEqual('one')
852+
);
853+
});

0 commit comments

Comments
 (0)