Skip to content

Commit a555e59

Browse files
authored
Merge pull request #690 from code16/improve-testing-global-filter
Improve testing global filter
2 parents f6dfd36 + b18c159 commit a555e59

13 files changed

Lines changed: 187 additions & 98 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->withSharpGlobalFilter(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/Commands/PendingCommand.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ public function __construct(
2121

2222
public function getForm(): AssertableCommandForm
2323
{
24-
$this->setGlobalFilterUrlDefault();
25-
2624
return new AssertableCommandForm(
2725
post: $this->post,
2826
getForm: $this->getForm,
@@ -33,8 +31,6 @@ public function getForm(): AssertableCommandForm
3331

3432
public function post(): AssertableCommand
3533
{
36-
$this->setGlobalFilterUrlDefault();
37-
3834
return new AssertableCommand(
3935
postCommand: $this->post,
4036
getForm: $this->getForm,

src/Utils/Testing/Dashboard/PendingDashboard.php

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Code16\Sharp\Utils\Testing\Commands\FormatsDataForCommand;
1111
use Code16\Sharp\Utils\Testing\Commands\PendingCommand;
1212
use Code16\Sharp\Utils\Testing\IsPendingComponent;
13+
use Code16\Sharp\Utils\Testing\SharpAssertions;
1314
use Code16\Sharp\Utils\Testing\Show\PendingShow;
1415
use Illuminate\Foundation\Testing\TestCase;
1516

@@ -23,7 +24,7 @@ class PendingDashboard
2324
protected array $filterValues = [];
2425

2526
public function __construct(
26-
/** @var TestCase $test */
27+
/** @var TestCase&SharpAssertions $test */
2728
protected object $test,
2829
string $entityKey,
2930
public ?PendingShow $parent = null,
@@ -42,8 +43,6 @@ public function withFilter(string $filterKey, mixed $value): static
4243

4344
public function get(): AssertableDashboard
4445
{
45-
$this->setGlobalFilterUrlDefault();
46-
4746
return new AssertableDashboard(
4847
$this->parent instanceof PendingShow
4948
? $this->test
@@ -69,8 +68,6 @@ public function get(): AssertableDashboard
6968

7069
public function dashboardCommand(string $commandKeyOrClassName): PendingCommand
7170
{
72-
$this->setGlobalFilterUrlDefault();
73-
7471
$commandKey = class_exists($commandKeyOrClassName)
7572
? class_basename($commandKeyOrClassName)
7673
: $commandKeyOrClassName;

src/Utils/Testing/EntityList/PendingEntityList.php

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Code16\Sharp\Utils\Testing\Commands\PendingCommand;
1212
use Code16\Sharp\Utils\Testing\Form\PendingForm;
1313
use Code16\Sharp\Utils\Testing\IsPendingComponent;
14+
use Code16\Sharp\Utils\Testing\SharpAssertions;
1415
use Code16\Sharp\Utils\Testing\Show\PendingShow;
1516
use Illuminate\Foundation\Testing\TestCase;
1617
use PHPUnit\Framework\Assert as PHPUnit;
@@ -25,7 +26,7 @@ class PendingEntityList
2526
protected array $filterValues = [];
2627

2728
public function __construct(
28-
/** @var TestCase $test */
29+
/** @var TestCase&SharpAssertions $test */
2930
protected object $test,
3031
string $entityKey,
3132
public ?PendingShow $parent = null,
@@ -50,16 +51,17 @@ public function sharpForm(string $entityClassNameOrKey, string|int $instanceId):
5051

5152
public function withFilter(string $filterKey, mixed $value): static
5253
{
53-
$key = $this->entityList->filterContainer()->findFilterHandler($filterKey)->getKey();
54-
$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;
5559

5660
return $this;
5761
}
5862

5963
public function get(): AssertableEntityList
6064
{
61-
$this->setGlobalFilterUrlDefault();
62-
6365
return new AssertableEntityList(
6466
$this->parent instanceof PendingShow
6567
? $this->test
@@ -85,8 +87,6 @@ public function get(): AssertableEntityList
8587

8688
public function entityCommand(string $commandKeyOrClassName): PendingCommand
8789
{
88-
$this->setGlobalFilterUrlDefault();
89-
9090
$commandKey = class_exists($commandKeyOrClassName)
9191
? class_basename($commandKeyOrClassName)
9292
: $commandKeyOrClassName;
@@ -134,8 +134,6 @@ public function entityCommand(string $commandKeyOrClassName): PendingCommand
134134

135135
public function instanceCommand(string $commandKeyOrClassName, int|string $instanceId): PendingCommand
136136
{
137-
$this->setGlobalFilterUrlDefault();
138-
139137
$commandKey = class_exists($commandKeyOrClassName)
140138
? class_basename($commandKeyOrClassName)
141139
: $commandKeyOrClassName;

src/Utils/Testing/Form/PendingForm.php

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
use Code16\Sharp\Form\SharpSingleForm;
77
use Code16\Sharp\Utils\Entities\SharpEntityManager;
88
use Code16\Sharp\Utils\Testing\EntityList\PendingEntityList;
9-
use Code16\Sharp\Utils\Testing\GeneratesGlobalFilterUrl;
109
use Code16\Sharp\Utils\Testing\IsPendingComponent;
10+
use Code16\Sharp\Utils\Testing\SharpAssertions;
1111
use Code16\Sharp\Utils\Testing\Show\PendingShow;
1212
use Illuminate\Foundation\Testing\TestCase;
1313
use Illuminate\Testing\TestResponse;
@@ -16,15 +16,14 @@
1616
class PendingForm
1717
{
1818
use FormatsDataForUpdate;
19-
use GeneratesGlobalFilterUrl;
2019
use IsPendingComponent;
2120

2221
public SharpForm $form;
2322
public string $entityKey;
2423
protected bool $isSubsequentRequest = false;
2524

2625
public function __construct(
27-
/** @var TestCase $test */
26+
/** @var TestCase&SharpAssertions $test */
2827
protected object $test,
2928
string $entityKey,
3029
public string|int|null $instanceId = null,
@@ -36,8 +35,6 @@ public function __construct(
3635

3736
public function create(): AssertableForm
3837
{
39-
$this->setGlobalFilterUrlDefault();
40-
4138
PHPUnit::assertNotInstanceOf(SharpSingleForm::class, $this->form);
4239

4340
return new AssertableForm(
@@ -52,8 +49,6 @@ public function create(): AssertableForm
5249

5350
public function edit(): AssertableForm
5451
{
55-
$this->setGlobalFilterUrlDefault();
56-
5752
if (! $this->form instanceof SharpSingleForm) {
5853
PHPUnit::assertNotNull($this->instanceId, 'You can’t edit a form without an instance ID.');
5954
}
@@ -71,8 +66,6 @@ public function edit(): AssertableForm
7166

7267
public function store(array $data): TestResponse
7368
{
74-
$this->setGlobalFilterUrlDefault();
75-
7669
PHPUnit::assertNotInstanceOf(SharpSingleForm::class, $this->form);
7770

7871
return $this->test
@@ -87,8 +80,6 @@ public function store(array $data): TestResponse
8780

8881
public function update(array $data): TestResponse
8982
{
90-
$this->setGlobalFilterUrlDefault();
91-
9283
if (! $this->form instanceof SharpSingleForm) {
9384
PHPUnit::assertNotNull($this->instanceId, 'You can’t update a form without an instance ID.');
9485
}

src/Utils/Testing/GeneratesGlobalFilterUrl.php

Lines changed: 0 additions & 24 deletions
This file was deleted.
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/IsPendingComponent.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
trait IsPendingComponent
1313
{
1414
use GeneratesCurrentPageUrl;
15-
use GeneratesGlobalFilterUrl;
1615

1716
protected function getParentUri(): string
1817
{

0 commit comments

Comments
 (0)