Skip to content

Commit c70c31e

Browse files
committed
Add tests for livewire components
1 parent 41b601f commit c70c31e

File tree

8 files changed

+438
-4
lines changed

8 files changed

+438
-4
lines changed

src/Livewire/ResponseStatusesGraph.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,11 @@ public function render(): Renderable
5151

5252
$recordStatusFlag = [];
5353
foreach (ResponseStatusGroup::cases() as $status) {
54-
if (in_array($status->value, Config::get('pulse.recorders.' . ResponsesStatistics::class . '.records', []))) {
55-
$recordStatusFlag['record_' . $status->name] = true;
56-
}
54+
$recordStatusFlag['record_' . $status->name] = in_array(
55+
$status->value,
56+
Config::get('pulse.recorders.' . ResponsesStatistics::class . '.records', []),
57+
true,
58+
);
5759
}
5860

5961
return View::make('api-usage-pulse::livewire.response-statuses-graph', [

testbench.example.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ workbench:
1616
web: false
1717
commands: false
1818
components: false
19-
views: false
19+
views: true
2020
build:
2121
- asset-publish
2222
- create-sqlite-db
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* Created by PhpStorm.
7+
* Author: Misha Serenkov
8+
9+
* Date: 19.02.2025 10:56
10+
*/
11+
12+
namespace Kodamity\Libraries\ApiUsagePulse\Tests\Livewire;
13+
14+
use Illuminate\Support\Collection;
15+
use Illuminate\Support\Facades\Gate;
16+
use Illuminate\Support\Facades\Hash;
17+
use Kodamity\Libraries\ApiUsagePulse\Livewire\RequestsSummary;
18+
use Kodamity\Libraries\ApiUsagePulse\Tests\TestCase;
19+
use Livewire\Livewire;
20+
use PHPUnit\Framework\Attributes\Test;
21+
use stdClass;
22+
use Workbench\App\Models\User;
23+
24+
class RequestsSummaryTest extends TestCase
25+
{
26+
protected User $user;
27+
28+
protected function setUp(): void
29+
{
30+
parent::setUp();
31+
32+
$this->user = User::create([
33+
'name' => 'Test',
34+
'email' => '[email protected]',
35+
'password' => Hash::make('test'),
36+
]);
37+
38+
Gate::define('viewPulse', fn ($user = null) => true);
39+
}
40+
41+
#[Test]
42+
public function it_exists_on_pulse_dashboard(): void
43+
{
44+
/* @phpstan-ignore method.notFound (Method 'assertSeeLivewire' exists but not resolved due to laravel magic) */
45+
$this
46+
->actingAs($this->user)
47+
->get('/pulse')
48+
->assertSeeLivewire(RequestsSummary::class);
49+
}
50+
51+
#[Test]
52+
public function it_displays_summary_of_requests(): void
53+
{
54+
$this->actingAs($this->user);
55+
56+
$this->get('/test/informational')->assertStatus(100);
57+
$this->get('/test/successful')->assertStatus(200);
58+
$this->get('/test/redirection')->assertStatus(302);
59+
$this->get('/test/client-error')->assertStatus(400);
60+
$this->get('/test/server-error')->assertStatus(500);
61+
62+
Livewire::actingAs($this->user)
63+
->withoutLazyLoading()
64+
->test(RequestsSummary::class)
65+
->assertSeeText('Requests Summary')
66+
->assertViewHas('totalRequests', function (stdClass $totalRequests) {
67+
return $totalRequests->total === 5 && $totalRequests->success === 1;
68+
});
69+
}
70+
71+
#[Test]
72+
public function it_displays_no_results(): void
73+
{
74+
$this->get('/test/informational')->assertStatus(100);
75+
$this->get('/test/client-error')->assertStatus(400);
76+
$this->get('/test/server-error')->assertStatus(500);
77+
78+
Livewire::actingAs($this->user)
79+
->withoutLazyLoading()
80+
->test(RequestsSummary::class)
81+
->assertSeeText('Requests Summary')
82+
->assertSeeText('No results')
83+
->assertViewHas('totalRequests', function (stdClass $totalRequests) {
84+
return $totalRequests->total === 0 && $totalRequests->success === 0;
85+
});
86+
}
87+
88+
#[Test]
89+
public function it_displays_requests_summary_for_clients(): void
90+
{
91+
$this->actingAs($this->user);
92+
93+
$this->get('/test/informational')->assertStatus(100);
94+
$this->get('/test/successful')->assertStatus(200);
95+
$this->get('/test/redirection')->assertStatus(302);
96+
$this->get('/test/client-error')->assertStatus(400);
97+
$this->get('/test/server-error')->assertStatus(500);
98+
99+
Livewire::actingAs($this->user)
100+
->withoutLazyLoading()
101+
->test(RequestsSummary::class)
102+
->assertSeeText('Requests Summary')
103+
->assertViewHas('requestsByKeys', function (Collection $requestsByKeys): bool {
104+
return $requestsByKeys->containsOneItem() &&
105+
$requestsByKeys->first(function (stdClass $item): bool {
106+
return $item->key === '1' && $item->total === 5 && $item->success === 1;
107+
});
108+
});
109+
}
110+
}
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* Created by PhpStorm.
7+
* Author: Misha Serenkov
8+
9+
* Date: 19.02.2025 13:24
10+
*/
11+
12+
namespace Kodamity\Libraries\ApiUsagePulse\Tests\Livewire;
13+
14+
use Illuminate\Support\Collection;
15+
use Illuminate\Support\Facades\Config;
16+
use Illuminate\Support\Facades\Date;
17+
use Illuminate\Support\Facades\Gate;
18+
use Illuminate\Support\Facades\Hash;
19+
use Illuminate\Support\Str;
20+
use Kodamity\Libraries\ApiUsagePulse\Enums\ResponseStatusGroup;
21+
use Kodamity\Libraries\ApiUsagePulse\Livewire\ResponseStatusesGraph;
22+
use Kodamity\Libraries\ApiUsagePulse\Recorders\ResponsesStatistics;
23+
use Kodamity\Libraries\ApiUsagePulse\Tests\Recorders\ResponsesStatisticsTest;
24+
use Kodamity\Libraries\ApiUsagePulse\Tests\TestCase;
25+
use Livewire\Livewire;
26+
use PHPUnit\Framework\Attributes\DataProviderExternal;
27+
use PHPUnit\Framework\Attributes\Test;
28+
use Workbench\App\Models\User;
29+
30+
class ResponseStatusesGraphTest extends TestCase
31+
{
32+
protected User $user;
33+
34+
protected function setUp(): void
35+
{
36+
parent::setUp();
37+
38+
$this->user = User::create([
39+
'name' => 'Test',
40+
'email' => '[email protected]',
41+
'password' => Hash::make('test'),
42+
]);
43+
44+
Gate::define('viewPulse', fn ($user = null) => true);
45+
}
46+
47+
#[Test]
48+
public function it_exists_on_pulse_dashboard(): void
49+
{
50+
/* @phpstan-ignore method.notFound (Method 'assertSeeLivewire' exists but not resolved due to laravel magic) */
51+
$this
52+
->actingAs($this->user)
53+
->get('/pulse')
54+
->assertSeeLivewire(ResponseStatusesGraph::class);
55+
}
56+
57+
#[Test]
58+
public function it_displays_no_results(): void
59+
{
60+
$this->get('/test/informational')->assertStatus(100);
61+
$this->get('/test/client-error')->assertStatus(400);
62+
$this->get('/test/server-error')->assertStatus(500);
63+
64+
Livewire::actingAs($this->user)
65+
->withoutLazyLoading()
66+
->test(ResponseStatusesGraph::class)
67+
->assertSeeText('Response Statuses')
68+
->assertSeeText('No results')
69+
->assertViewHas('datasets', static fn (Collection $datasets) => $datasets->isEmpty());
70+
}
71+
72+
#[Test, DataProviderExternal(ResponsesStatisticsTest::class, 'responseStatusGroupsProvider')]
73+
public function it_displays_graph_of_one_of_response_statuses_group(ResponseStatusGroup $statusGroup, int $expectedStatusCode): void
74+
{
75+
Date::setTestNow('2025-02-18 03:04:05');
76+
77+
$testUrl = Str::of($statusGroup->name)->kebab()->prepend('/test/')->toString();
78+
79+
Config::set('pulse.recorders.' . ResponsesStatistics::class . '.records', [$statusGroup->value]);
80+
81+
$this->get($testUrl)->assertStatus($expectedStatusCode);
82+
83+
Livewire::actingAs($this->user)
84+
->withoutLazyLoading()
85+
->test(ResponseStatusesGraph::class)
86+
->assertSeeText('Response Statuses')
87+
->assertSeeText(sprintf('%dxx', ((string)$expectedStatusCode)[0]))
88+
->assertViewHas('datasets', function (Collection $datasets) use ($statusGroup): bool {
89+
$conditions = $datasets
90+
->map(function (Collection $dataset, $key) use ($statusGroup): bool {
91+
if ($key === $statusGroup->name) {
92+
return $dataset->filter()->containsOneItem();
93+
}
94+
95+
return $dataset->filter()->isEmpty();
96+
})
97+
->values()
98+
->all();
99+
100+
return !in_array(false, $conditions, true);
101+
});
102+
}
103+
104+
#[Test]
105+
public function it_displays_graph_of_all_of_response_statuses_group(): void
106+
{
107+
Date::setTestNow('2025-02-18 03:04:05');
108+
109+
Config::set('pulse.recorders.' . ResponsesStatistics::class . '.records', array_map(
110+
fn (ResponseStatusGroup $statusGroup) => $statusGroup->value,
111+
ResponseStatusGroup::cases(),
112+
));
113+
114+
$this->get('/test/informational')->assertStatus(100);
115+
$this->get('/test/successful')->assertStatus(200);
116+
$this->get('/test/redirection')->assertStatus(302);
117+
$this->get('/test/client-error')->assertStatus(400);
118+
$this->get('/test/server-error')->assertStatus(500);
119+
120+
Livewire::actingAs($this->user)
121+
->withoutLazyLoading()
122+
->test(ResponseStatusesGraph::class)
123+
->assertSeeText('Response Statuses')
124+
->assertSeeTextInOrder(['1xx', '2xx', '3xx', '4xx', '5xx'])
125+
->assertViewHas('datasets', function (Collection $datasets): bool {
126+
$conditions = $datasets
127+
->map(fn (Collection $dataset): bool => $dataset->filter()->containsOneItem())
128+
->values()
129+
->all();
130+
131+
return !in_array(false, $conditions, true);
132+
});
133+
}
134+
135+
#[Test]
136+
public function it_dispatches_updated_response_statuses_graph_event(): void
137+
{
138+
Date::setTestNow('2025-02-18 03:04:05');
139+
140+
Config::set('pulse.recorders.' . ResponsesStatistics::class . '.ignore', [
141+
'#^/livewire#',
142+
]);
143+
Config::set('pulse.recorders.' . ResponsesStatistics::class . '.records', array_map(
144+
fn (ResponseStatusGroup $statusGroup) => $statusGroup->value,
145+
ResponseStatusGroup::cases(),
146+
));
147+
148+
$component = Livewire::actingAs($this->user)
149+
->withoutLazyLoading()
150+
->test(ResponseStatusesGraph::class)
151+
->assertSeeText('Response Statuses')
152+
->assertSeeText('No results');
153+
154+
Date::setTestNow('2025-02-18 03:05:05');
155+
156+
$this->get('/test/informational')->assertStatus(100);
157+
$this->get('/test/successful')->assertStatus(200);
158+
$this->get('/test/redirection')->assertStatus(302);
159+
$this->get('/test/client-error')->assertStatus(400);
160+
$this->get('/test/server-error')->assertStatus(500);
161+
162+
$component->update()
163+
->assertDispatched('kdm-api-usage-response-statuses-chart-update', function (string $eventName, array $params) {
164+
$conditions = collect($params['datasets'] ?? [])
165+
->map(fn (array $dataset): bool => collect($dataset)->filter()->containsOneItem())
166+
->values()
167+
->all();
168+
169+
return !in_array(false, $conditions, true);
170+
});
171+
}
172+
}

0 commit comments

Comments
 (0)