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
11 changes: 11 additions & 0 deletions ide.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,17 @@
"parameters": [
1
]
},
{
"classFqn": [
"Code16\\Sharp\\Utils\\Testing\\Commands\\AssertableCommand"
],
"methodNames": [
"assertReturnsView"
],
"parameters": [
1
]
}
]
},
Expand Down
4 changes: 4 additions & 0 deletions src/Http/Controllers/ShowController.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ public function show(string $globalFilter, string $parentUri, EntityKey $entityK

$this->addPreloadHeadersForShowEntityLists($payload);

if (app()->environment('testing')) {
Inertia::share('_rawData', $showData);
}

return Inertia::render('Show/Show', [
'show' => $payload,
'breadcrumb' => BreadcrumbData::from([
Expand Down
4 changes: 4 additions & 0 deletions src/Http/Controllers/SingleShowController.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ public function show(string $globalFilter, EntityKey $entityKey)

$this->addPreloadHeadersForShowEntityLists($payload);

if (app()->environment('testing')) {
Inertia::share('_rawData', $showData);
}

return Inertia::render('Show/Show', [
'show' => $payload,
'breadcrumb' => BreadcrumbData::from([
Expand Down
170 changes: 170 additions & 0 deletions src/Utils/Testing/Commands/AssertableCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
<?php

namespace Code16\Sharp\Utils\Testing\Commands;

use Closure;
use Code16\Sharp\Dashboard\SharpDashboard;
use Code16\Sharp\EntityList\SharpEntityList;
use Code16\Sharp\Show\SharpShow;
use Code16\Sharp\Utils\Testing\DelegatesToResponse;
use Illuminate\Support\Facades;
use Illuminate\Support\Str;
use Illuminate\Testing\Fluent\AssertableJson;
use Illuminate\Testing\TestResponse;
use Illuminate\View\View;
use PHPUnit\Framework\Assert as PHPUnit;

class AssertableCommand
{
use DelegatesToResponse;

public ?View $createdView = null;

public function __construct(
/** @var Closure(array,string): TestResponse */
protected Closure $postCommand,
protected SharpEntityList|SharpShow|SharpDashboard $commandContainer,
protected array $data = [],
protected ?string $step = null,
) {
$this->response = $this->post();
}

public function assertViewHas(mixed $key, mixed $value = null): static
{
$this->response->original = $this->createdView;
$this->response->assertViewHas($key, $value);

return $this;
}

public function assertViewHasAll(mixed $bindings): static
{
$this->response->original = $this->createdView;
$this->response->assertViewHas($bindings);

return $this;
}

public function assertViewIs($value)
{
$this->response->original = $this->createdView;
$this->response->assertViewIs($value);

return $this;
}

public function assertReturnsView(?string $view = null, ?array $data = null): static
{
$this->response->assertJson(fn (AssertableJson $json) => $json
->where('action', 'view')
->etc()
);

if ($view) {
$this->assertViewIs($view);
}

if ($data) {
$this->assertViewHasAll($data);
}

return $this;
}

public function assertReturnsInfo(string $message = ''): static
{
$this->response->assertJson(fn (AssertableJson $json) => $json
->where('action', 'info')
->when($message)->where('message', $message)
->etc()
);

return $this;
}

public function assertReturnsLink(string $url = ''): static
{
$this->response->assertJson(fn (AssertableJson $json) => $json
->where('action', 'link')
->when($url)->where('link', $url)
->etc()
);

return $this;
}

public function assertReturnsReload(): static
{
$this->response->assertJson(fn (AssertableJson $json) => $json
->where('action', 'reload')
->etc()
);

return $this;
}

public function assertReturnsRefresh(array $ids): static
{
$this->response->assertJson(fn (AssertableJson $json) => $json
->where('action', 'refresh')
->etc()
);

PHPUnit::assertEqualsCanonicalizing(
$ids,
collect($this->response->json('items'))->pluck($this->commandContainer->getInstanceIdAttribute())->all()
);

return $this;
}

public function assertReturnsStep(?string $step = null): static
{
$this->response->assertJson(fn (AssertableJson $json) => $json
->where('action', 'step')
->etc()
);

if ($step) {
PHPUnit::assertEquals($step, Str::before($this->response->json('step'), ':'));
}

return $this;
}

public function assertReturnsDownload(?string $filename = null): static
{
$this->response->assertStreamed();

if ($filename) {
preg_match('/filename="?([^";]+)"?/', $this->response->headers->get('Content-Disposition'), $matches);
PHPUnit::assertEquals($filename, $matches[1] ?? null);
}

return $this;
}

public function callNextStep(array $data = []): static
{
$this->assertReturnsStep();

return new AssertableCommand(
$this->postCommand,
commandContainer: $this->commandContainer,
data: $data,
step: $this->response->json('step'),
);
}

protected function post(): TestResponse
{
Facades\View::creator('*', function (View $view) {
$this->createdView = $view;
});

return tap(($this->postCommand)($this->data, $this->step), function () {
Facades\Event::forget('creating: *');
});
}
}
22 changes: 22 additions & 0 deletions src/Utils/Testing/DelegatesToResponse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace Code16\Sharp\Utils\Testing;

use Illuminate\Testing\TestResponse;

/**
* @method
*
* @mixin TestResponse
*/
trait DelegatesToResponse
{
protected TestResponse $response;

public function __call(string $name, array $arguments)
{
$this->response->{$name}(...$arguments);

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

namespace Code16\Sharp\Utils\Testing\EntityList;

use Code16\Sharp\Utils\Testing\DelegatesToResponse;
use Illuminate\Testing\TestResponse;
use PHPUnit\Framework\Assert as PHPUnit;

class AssertableEntityList
{
use DelegatesToResponse;

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

public function assertListCount(int $count): self
{
PHPUnit::assertCount($count, $this->listData());

return $this;
}

public function assertListContains(array $attributes): self
{
PHPUnit::assertTrue(
collect($this->listData())->contains(fn ($item) => collect($attributes)->every(fn ($value, $key) => isset($item[$key]) && $item[$key] === $value)
),
sprintf(
'Failed asserting that data contains an item with attributes: %s',
json_encode($attributes)
)
);

return $this;
}

protected function listData(): array
{
return $this->response->inertiaProps('entityList.data');
}
}
Loading
Loading