Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions src/Utils/Testing/EntityList/AssertableEntityList.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace Code16\Sharp\Utils\Testing\EntityList;

use Illuminate\Testing\TestResponse;

class AssertableEntityList
{
public function __construct(
protected TestResponse $response,
) {}

public function assertOk(): self
{
$this->response->assertOk();

return $this;
}
}
53 changes: 53 additions & 0 deletions src/Utils/Testing/EntityList/PendingEntityList.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace Code16\Sharp\Utils\Testing\EntityList;

use Code16\Sharp\EntityList\SharpEntityList;
use Code16\Sharp\Utils\Entities\SharpEntityManager;
use Code16\Sharp\Utils\Testing\GeneratesSharpUrl;
use Illuminate\Foundation\Testing\Concerns\MakesHttpRequests;

class PendingEntityList
{
use GeneratesSharpUrl;

protected SharpEntityList $entityList;
protected array $filterValues = [];

public function __construct(
/** @var MakesHttpRequests $test */
protected object $test,
protected string $entityKey
) {
$resolvedEntityKey = app(SharpEntityManager::class)->entityKeyFor($this->entityKey);
$this->entityList = app(SharpEntityManager::class)->entityFor($resolvedEntityKey)->getListOrFail();
}

public function withFilter(string $filterKey, mixed $value): static
{
$key = $this->entityList->filterContainer()->findFilterHandler($filterKey)->getKey();
$this->filterValues[$key] = $value;

return $this;
}

public function get(): AssertableEntityList
{
$this->setGlobalFilterUrlDefault();

return new AssertableEntityList(
$this->test->get(
route('code16.sharp.list', [
'entityKey' => $this->entityKey,
...$this->entityList
->filterContainer()
->getQueryParamsFromFilterValues($this->filterValues),
])
)
);
}

public function callInstanceCommand() {}

public function callEntityCommand() {}
}
64 changes: 64 additions & 0 deletions src/Utils/Testing/GeneratesSharpUrl.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
<?php

namespace Code16\Sharp\Utils\Testing;

use Closure;
use Code16\Sharp\Filters\GlobalFilters\GlobalFilters;
use Code16\Sharp\Utils\Links\BreadcrumbBuilder;
use Illuminate\Support\Facades\URL;

/**
* @internal
*/
trait GeneratesSharpUrl
{
private BreadcrumbBuilder $breadcrumbBuilder;
private ?string $globalFilter = null;

/**
* @param (\Closure(BreadcrumbBuilder): BreadcrumbBuilder) $callback
* @return $this
*/
public function withSharpBreadcrumb(Closure $callback): self
{
$this->breadcrumbBuilder = $callback(new BreadcrumbBuilder());

return $this;
}

public function withSharpGlobalFilterValues(array|string $globalFilterValues): self
{
$this->globalFilter = collect((array) $globalFilterValues)
->implode(GlobalFilters::$valuesUrlSeparator);

return $this;
}

private function setGlobalFilterUrlDefault(): void
{
URL::defaults(['globalFilter' => $this->globalFilter ?: GlobalFilters::$defaultKey]);
}

private function breadcrumbBuilder(string $entityKey, ?string $instanceId = null): BreadcrumbBuilder
{
if (isset($this->breadcrumbBuilder)) {
return $this->breadcrumbBuilder;
}

return (new BreadcrumbBuilder())
->appendEntityList($entityKey)
->when($instanceId, fn ($builder) => $builder->appendShowPage($entityKey, $instanceId));
}

private function buildCurrentPageUrl(BreadcrumbBuilder $builder): string
{
return url(
sprintf(
'/%s/%s/%s',
sharp()->config()->get('custom_url_segment'),
sharp()->context()->globalFilterUrlSegmentValue(),
$builder->generateUri()
)
);
}
}
76 changes: 18 additions & 58 deletions src/Utils/Testing/SharpAssertions.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@

namespace Code16\Sharp\Utils\Testing;

use Closure;
use Code16\Sharp\Filters\GlobalFilters\GlobalFilters;
use Code16\Sharp\Http\Context\SharpBreadcrumb;
use Code16\Sharp\Utils\Entities\SharpEntityManager;
use Code16\Sharp\Utils\Links\BreadcrumbBuilder;
use Illuminate\Support\Facades\URL;
use Code16\Sharp\Utils\Testing\EntityList\PendingEntityList;

trait SharpAssertions
{
private BreadcrumbBuilder $breadcrumbBuilder;
private ?string $globalFilter = null;
use GeneratesSharpUrl;

public function sharpList(string $entityClassNameOrKey): PendingEntityList
{
return new PendingEntityList($this, $entityClassNameOrKey);
}

/**
* @deprecated use withSharpBreadcrumb() instead
Expand All @@ -32,28 +34,9 @@ public function withSharpCurrentBreadcrumb(...$breadcrumb): self
return $this;
}

/**
* @param (\Closure(BreadcrumbBuilder): BreadcrumbBuilder) $callback
* @return $this
*/
public function withSharpBreadcrumb(Closure $callback): self
{
$this->breadcrumbBuilder = $callback(new BreadcrumbBuilder());

return $this;
}

public function withSharpGlobalFilterValues(array|string $globalFilterValues): self
{
$this->globalFilter = collect((array) $globalFilterValues)
->implode(GlobalFilters::$valuesUrlSeparator);

return $this;
}

public function deleteFromSharpShow(string $entityClassNameOrKey, mixed $instanceId)
{
URL::defaults(['globalFilter' => $this->globalFilter ?: GlobalFilters::$defaultKey]);
$this->setGlobalFilterUrlDefault();

$entityKey = $this->resolveEntityKey($entityClassNameOrKey);

Expand All @@ -72,7 +55,7 @@ public function deleteFromSharpShow(string $entityClassNameOrKey, mixed $instanc

public function deleteFromSharpList(string $entityClassNameOrKey, mixed $instanceId)
{
URL::defaults(['globalFilter' => $this->globalFilter ?: GlobalFilters::$defaultKey]);
$this->setGlobalFilterUrlDefault();

$entityKey = $this->resolveEntityKey($entityClassNameOrKey);

Expand All @@ -94,7 +77,7 @@ public function deleteFromSharpList(string $entityClassNameOrKey, mixed $instanc

public function getSharpForm(string $entityClassNameOrKey, mixed $instanceId = null)
{
URL::defaults(['globalFilter' => $this->globalFilter ?: GlobalFilters::$defaultKey]);
$this->setGlobalFilterUrlDefault();

$entityKey = $this->resolveEntityKey($entityClassNameOrKey);

Expand Down Expand Up @@ -123,7 +106,7 @@ public function getSharpForm(string $entityClassNameOrKey, mixed $instanceId = n

public function getSharpSingleForm(string $entityClassNameOrKey)
{
URL::defaults(['globalFilter' => $this->globalFilter ?: GlobalFilters::$defaultKey]);
$this->setGlobalFilterUrlDefault();

$entityKey = $this->resolveEntityKey($entityClassNameOrKey);

Expand All @@ -142,7 +125,7 @@ public function getSharpSingleForm(string $entityClassNameOrKey)

public function updateSharpForm(string $entityClassNameOrKey, $instanceId, array $data)
{
URL::defaults(['globalFilter' => $this->globalFilter ?: GlobalFilters::$defaultKey]);
$this->setGlobalFilterUrlDefault();

$entityKey = $this->resolveEntityKey($entityClassNameOrKey);

Expand All @@ -162,7 +145,7 @@ public function updateSharpForm(string $entityClassNameOrKey, $instanceId, array

public function updateSharpSingleForm(string $entityClassNameOrKey, array $data)
{
URL::defaults(['globalFilter' => $this->globalFilter ?: GlobalFilters::$defaultKey]);
$this->setGlobalFilterUrlDefault();

$entityKey = $this->resolveEntityKey($entityClassNameOrKey);

Expand All @@ -181,7 +164,7 @@ public function updateSharpSingleForm(string $entityClassNameOrKey, array $data)

public function getSharpShow(string $entityClassNameOrKey, $instanceId)
{
URL::defaults(['globalFilter' => $this->globalFilter ?: GlobalFilters::$defaultKey]);
$this->setGlobalFilterUrlDefault();

$entityKey = $this->resolveEntityKey($entityClassNameOrKey);

Expand All @@ -201,7 +184,7 @@ public function getSharpShow(string $entityClassNameOrKey, $instanceId)

public function storeSharpForm(string $entityClassNameOrKey, array $data)
{
URL::defaults(['globalFilter' => $this->globalFilter ?: GlobalFilters::$defaultKey]);
$this->setGlobalFilterUrlDefault();

$entityKey = $this->resolveEntityKey($entityClassNameOrKey);

Expand All @@ -226,7 +209,7 @@ public function callSharpInstanceCommandFromList(
array $data = [],
?string $commandStep = null
) {
URL::defaults(['globalFilter' => $this->globalFilter ?: GlobalFilters::$defaultKey]);
$this->setGlobalFilterUrlDefault();

$entityKey = $this->resolveEntityKey($entityClassNameOrKey);

Expand Down Expand Up @@ -257,7 +240,7 @@ public function callSharpInstanceCommandFromShow(
array $data = [],
?string $commandStep = null
) {
URL::defaults(['globalFilter' => $this->globalFilter ?: GlobalFilters::$defaultKey]);
$this->setGlobalFilterUrlDefault();

$entityKey = $this->resolveEntityKey($entityClassNameOrKey);

Expand Down Expand Up @@ -287,7 +270,7 @@ public function callSharpEntityCommandFromList(
array $data = [],
?string $commandStep = null
) {
URL::defaults(['globalFilter' => $this->globalFilter ?: GlobalFilters::$defaultKey]);
$this->setGlobalFilterUrlDefault();

$entityKey = $this->resolveEntityKey($entityClassNameOrKey);

Expand All @@ -311,29 +294,6 @@ public function loginAsSharpUser($user): self
return $this->actingAs($user, sharp()->config()->get('auth.guard') ?: config('auth.defaults.guard'));
}

private function breadcrumbBuilder(string $entityKey, ?string $instanceId = null): BreadcrumbBuilder
{
if (isset($this->breadcrumbBuilder)) {
return $this->breadcrumbBuilder;
}

return (new BreadcrumbBuilder())
->appendEntityList($entityKey)
->when($instanceId, fn ($builder) => $builder->appendShowPage($entityKey, $instanceId));
}

private function buildCurrentPageUrl(BreadcrumbBuilder $builder): string
{
return url(
sprintf(
'/%s/%s/%s',
sharp()->config()->get('custom_url_segment'),
sharp()->context()->globalFilterUrlSegmentValue(),
$builder->generateUri()
)
);
}

private function resolveEntityKey(string $entityClassNameOrKey): string
{
return app(SharpEntityManager::class)->entityKeyFor($entityClassNameOrKey);
Expand Down
59 changes: 56 additions & 3 deletions tests/Unit/Utils/Testing/SharpAssertionsTest.php
Original file line number Diff line number Diff line change
@@ -1,9 +1,55 @@
<?php

use Code16\Sharp\Filters\SelectFilter;
use Code16\Sharp\Tests\Fixtures\Entities\PersonEntity;
use Code16\Sharp\Tests\Fixtures\Sharp\PersonList;
use Code16\Sharp\Utils\Testing\SharpAssertions;
use Illuminate\Support\Traits\Tappable;

uses(SharpAssertions::class);

beforeEach(function () {
sharp()->config()->declareEntity(PersonEntity::class);
});

it('allows to test entity list', function () {
fakeListFor(PersonEntity::class, new class() extends PersonList
{
public function getFilters(): ?array
{
return [
new class() extends SelectFilter
{
public function buildFilterConfig(): void
{
$this->configureKey('job');
}

public function values(): array
{
return [
'physicist' => 'Physicist',
'physician' => 'Physician',
];
}
},
];
}
});

$response = fakeResponse();
$response->sharpList('person')
->withFilter('job', 'physicist')
->get();

expect($response->uri)->toEqual(
route('code16.sharp.list', [
'entityKey' => 'person',
'filter_job' => 'physicist',
])
);
});

it('allows to test getSharpShow', function () {
$response = fakeResponse()->getSharpShow('leaves', 6);

Expand Down Expand Up @@ -249,9 +295,10 @@ function fakeResponse()
return new class('fake') extends Orchestra\Testbench\TestCase
{
use SharpAssertions;
use Tappable;

public $uri;
public $postedData;
public string $uri;
public mixed $postedData;

public function call($method, $uri, $parameters = [], $cookies = [], $files = [], $server = [], $content = null)
{
Expand All @@ -265,7 +312,13 @@ public function call($method, $uri, $parameters = [], $cookies = [], $files = []
$this->postedData = null;
}

return $this;
return new class($this->uri, $this->postedData) extends \Illuminate\Testing\TestResponse
{
public function __construct(public $uri, public $postedData)
{
parent::__construct(new \Illuminate\Http\Response());
}
};
}
};
}
Loading