Compare commits

...

7 Commits

Author SHA1 Message Date
Lance Pioch
1d7675caca Fix import order 2026-06-12 10:40:04 -04:00
Lance Pioch
f0dfadda98 Add Feature and Filament suites to phpunit config 2026-06-12 10:34:44 -04:00
Lance Pioch
d1b7ac026b Fix Filament admin list tests 2026-06-12 10:34:44 -04:00
Lance Pioch
476ce81ebc Update webhook tests for current payload format 2026-06-12 10:34:44 -04:00
Lance Pioch
07f1dfe8b8 Use auth type data provider in SFTP throttle test 2026-06-12 10:34:44 -04:00
Lance Pioch
2fd3833e95 Fix data provider arity warnings in ConvertToUtf8Test 2026-06-12 10:34:44 -04:00
Lance Pioch
234d4f0c0d Fix webhook payload serialization and null headers 2026-06-12 10:34:44 -04:00
10 changed files with 38 additions and 36 deletions

View File

@@ -7,6 +7,7 @@ use App\Models\WebhookConfiguration;
use Exception;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
@@ -34,7 +35,9 @@ class ProcessWebhook implements ShouldQueue
$data = reset($data);
}
if (is_object($data)) {
if ($data instanceof Arrayable) {
$data = $data->toArray();
} elseif (is_object($data)) {
$data = get_object_vars($data);
}
@@ -64,7 +67,7 @@ class ProcessWebhook implements ShouldQueue
$headers = [];
if ($this->webhookConfiguration->type === WebhookType::Regular) {
foreach ($this->webhookConfiguration->headers as $key => $value) {
foreach ($this->webhookConfiguration->headers ?? [] as $key => $value) {
$headers[$key] = $this->webhookConfiguration->replaceVars($data, $value);
}
}

View File

@@ -1,17 +0,0 @@
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
class PermissionFactory extends Factory
{
protected $model = Permission::class;
public function definition(): array
{
return [
];
}
}

View File

@@ -11,6 +11,12 @@
<testsuite name="Unit">
<directory>./tests/Unit</directory>
</testsuite>
<testsuite name="Feature">
<directory>./tests/Feature</directory>
</testsuite>
<testsuite name="Filament">
<directory>./tests/Filament</directory>
</testsuite>
</testsuites>
<php>
<env name="APP_ENV" value="testing"/>

View File

@@ -68,7 +68,7 @@ class DispatchWebhooksTest extends TestCase
'events' => ['eloquent.created: '.Server::class],
]);
$webhookConfig->update(['events' => 'eloquent.deleted: '.Server::class]);
$webhookConfig->update(['events' => ['eloquent.deleted: '.Server::class]]);
$this->createServer();

View File

@@ -64,7 +64,7 @@ class ProcessWebhooksTest extends TestCase
ProcessWebhook::dispatchSync(
$webhook,
'eloquent.created: '.Server::class,
$data,
[$data],
);
$this->assertCount(1, cache()->get("webhooks.$eventName"));
@@ -73,7 +73,7 @@ class ProcessWebhooksTest extends TestCase
Http::assertSentCount(1);
Http::assertSent(function (Request $request) use ($webhook, $data) {
return $webhook->endpoint === $request->url()
&& $request->data() === $data;
&& $request->data() === array_merge($data, ['event' => 'created: Server']);
});
}
@@ -143,7 +143,7 @@ class ProcessWebhooksTest extends TestCase
$this->assertDatabaseCount(Webhook::class, 1);
$webhook = Webhook::query()->first();
$this->assertEquals($server->uuid, $webhook->payload[0]['uuid']);
$this->assertEquals($server->uuid, $webhook->payload['uuid']);
$this->assertDatabaseHas(Webhook::class, [
'endpoint' => $webhookConfig->endpoint,
@@ -165,8 +165,11 @@ class ProcessWebhooksTest extends TestCase
$server = $this->createServer();
$this->assertDatabaseCount(Webhook::class, 1);
$webhook = Webhook::query()->first();
$this->assertEquals($server->uuid, $webhook->payload['uuid']);
$this->assertDatabaseHas(Webhook::class, [
'payload' => json_encode([$server->toArray()]),
'endpoint' => $webhookConfig->endpoint,
'successful_at' => null,
'event' => 'eloquent.created: '.Server::class,

View File

@@ -4,6 +4,7 @@ use App\Enums\RolePermissionModels;
use App\Filament\Admin\Resources\Eggs\Pages\ListEggs;
use App\Models\Egg;
use App\Models\Role;
use Spatie\Permission\Models\Permission;
use function Pest\Livewire\livewire;
@@ -22,7 +23,7 @@ it('root admin can see all eggs', function () {
it('non root admin cannot see any eggs', function () {
$role = Role::factory()->create(['name' => 'Node Viewer', 'guard_name' => 'web']);
// Node Permission is on purpose, we check the wrong permissions.
$permission = Permission::factory()->create(['name' => RolePermissionModels::Node->viewAny(), 'guard_name' => 'web']);
$permission = Permission::create(['name' => RolePermissionModels::Node->viewAny(), 'guard_name' => 'web']);
$role->permissions()->attach($permission);
[$user] = generateTestAccount([]);
@@ -33,7 +34,7 @@ it('non root admin cannot see any eggs', function () {
it('non root admin with permissions can see eggs', function () {
$role = Role::factory()->create(['name' => 'Egg Viewer', 'guard_name' => 'web']);
$permission = Permission::factory()->create(['name' => RolePermissionModels::Egg->viewAny(), 'guard_name' => 'web']);
$permission = Permission::create(['name' => RolePermissionModels::Egg->viewAny(), 'guard_name' => 'web']);
$role->permissions()->attach($permission);
$eggs = Egg::all();

View File

@@ -5,7 +5,8 @@ use App\Filament\Admin\Resources\Nodes\Pages\ListNodes;
use App\Models\Node;
use App\Models\Role;
use App\Models\Server;
use Filament\Actions\CreateAction;
use Filament\Actions\Testing\TestAction;
use Spatie\Permission\Models\Permission;
use function Pest\Livewire\livewire;
@@ -24,7 +25,7 @@ it('root admin can see all nodes', function () {
it('non root admin cannot see any nodes', function () {
$role = Role::factory()->create(['name' => 'Egg Viewer', 'guard_name' => 'web']);
// Egg Permission is on purpose, we check the wrong permissions.
$permission = Permission::factory()->create(['name' => RolePermissionModels::Egg->viewAny(), 'guard_name' => 'web']);
$permission = Permission::create(['name' => RolePermissionModels::Egg->viewAny(), 'guard_name' => 'web']);
$role->permissions()->attach($permission);
[$user] = generateTestAccount();
@@ -35,7 +36,7 @@ it('non root admin cannot see any nodes', function () {
it('non root admin with permissions can see nodes', function () {
$role = Role::factory()->create(['name' => 'Node Viewer', 'guard_name' => 'web']);
$permission = Permission::factory()->create(['name' => RolePermissionModels::Node->viewAny(), 'guard_name' => 'web']);
$permission = Permission::create(['name' => RolePermissionModels::Node->viewAny(), 'guard_name' => 'web']);
$role->permissions()->attach($permission);
[$user] = generateTestAccount();
@@ -60,6 +61,6 @@ it('displays the create button in the table instead of the header when 0 nodes',
$this->actingAs($admin);
livewire(ListNodes::class)
->assertSuccessful()
->assertHeaderMissing(CreateAction::class)
->assertActionExists(CreateAction::class);
->assertActionDoesNotExist('create')
->assertActionExists(TestAction::make('create')->table());
});

View File

@@ -99,11 +99,11 @@ class SftpAuthenticationControllerTest extends IntegrationTestCase
* the endpoint.
*/
#[DataProvider('authorizationTypeDataProvider')]
public function test_user_is_throttled_if_invalid_credentials_are_provided(): void
public function test_user_is_throttled_if_invalid_credentials_are_provided(string $type): void
{
for ($i = 0; $i <= 10; $i++) {
$this->postJson('/api/remote/sftp/auth', [
'type' => 'public_key',
'type' => $type,
'username' => $i % 2 === 0 ? $this->user->username : $this->getUsername(),
'password' => 'invalid key',
])

View File

@@ -32,6 +32,7 @@ use App\Models\Server;
use App\Models\Subuser;
use App\Models\User;
use App\Tests\Integration\IntegrationTestCase;
use Filament\Facades\Filament;
use Ramsey\Uuid\Uuid;
expect()->extend('toBeOne', function () {
@@ -42,7 +43,11 @@ expect()->extend('toLogActivities', function (int $times) {
expect(ActivityLog::count())->toBe($times);
});
uses(IntegrationTestCase::class)->in('Feature', 'Filament');
uses(IntegrationTestCase::class)->in('Feature');
uses(IntegrationTestCase::class)
->beforeEach(fn () => Filament::setCurrentPanel('admin'))
->in('Filament');
/*
|--------------------------------------------------------------------------

View File

@@ -18,7 +18,7 @@ class ConvertToUtf8Test extends TestCase
* Every output must be valid UTF-8, regardless of input encoding.
*/
#[DataProvider('helperDataProvider')]
public function test_output_is_valid_utf8(string $input): void
public function test_output_is_valid_utf8(string $input, string $expected): void
{
$result = convert_to_utf8($input);
$this->assertTrue(mb_check_encoding($result, 'UTF-8'), 'Output is not valid UTF-8: ' . bin2hex($result));
@@ -28,7 +28,7 @@ class ConvertToUtf8Test extends TestCase
* Running convert_to_utf8 twice must produce the same result as once.
*/
#[DataProvider('helperDataProvider')]
public function test_idempotent(string $input): void
public function test_idempotent(string $input, string $expected): void
{
$once = convert_to_utf8($input);
$twice = convert_to_utf8($once);