Skip to content

Commit 59f4853

Browse files
Merge pull request #1442 from liberu-genealogy/copilot/fix-mysql-install-test-workflow
[WIP] Fix MySQL on install and update workflow actions
2 parents a6c76f0 + 22e503d commit 59f4853

21 files changed

+188
-545
lines changed

.env.testing

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ DB_TENANT_DATABASE=tenant
1010
LOG_CHANNEL=stack
1111

1212
DB_CONNECTION=mysql
13-
DB_HOST=localhost
13+
DB_HOST=127.0.0.1
1414
DB_PORT=3306
1515
DB_DATABASE=liberu
1616
DB_USERNAME=root

.github/workflows/security.yml

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ jobs:
3939
run: |
4040
composer install --prefer-dist --no-progress
4141
test -f phpcpd.phar || curl -L https://phar.phpunit.de/phpcpd.phar -o phpcpd.phar
42-
php phpcpd.phar app/
42+
php phpcpd.phar --min-lines=30 app/
4343
44-
php-insights:
44+
security:
4545
runs-on: ubuntu-24.04
4646
steps:
4747
- uses: actions/checkout@v4
@@ -61,24 +61,8 @@ jobs:
6161
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
6262
restore-keys: ${{ runner.os }}-composer-
6363

64-
- name: 'Run php-insight'
64+
- name: 'Run composer audit for security vulnerabilities'
6565
run: |
6666
composer install --prefer-dist --no-progress
67-
php artisan insights --min-quality=90 --min-complexity=90 --min-architecture=80 --min-style=90 --no-interaction
68-
69-
security:
70-
runs-on: ubuntu-24.04
71-
steps:
72-
- uses: actions/checkout@v4
73-
- uses: shivammathur/setup-php@v2
74-
with:
75-
php-version: '8.5'
76-
77-
- name: 'Run php security checker'
78-
run: |
79-
PHP_SC_VERSION=$(curl -s "https://api.github.com/repos/fabpot/local-php-security-checker/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/;s/^v//')
80-
curl -LSs https://github.com/fabpot/local-php-security-checker/releases/download/v${PHP_SC_VERSION}/local-php-security-checker_${PHP_SC_VERSION}_linux_amd64 > ./php-security-checker
81-
chmod +x ./php-security-checker
82-
unset PHP_SC_VERSION
83-
./php-security-checker
67+
composer audit
8468

app/Filament/App/Resources/GedcomResource.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
use Filament\Actions\DeleteBulkAction;
1616
use BackedEnum;
1717
use App\Filament\App\Resources\GedcomResource\Pages;
18-
use App\Jobs\ExportGedcom;
18+
use App\Jobs\ExportGedCom;
1919
use App\Jobs\ExportGrampsXml;
2020
use App\Jobs\ImportGedcom;
2121
use App\Jobs\ImportGrampsXml;
@@ -133,14 +133,20 @@ public static function table(Table $table): Table
133133

134134
public static function exportGedcom(): void
135135
{
136-
$user = auth()->user(); // Assuming the user is authenticated
136+
$user = auth()->user();
137+
if (! $user) {
138+
return;
139+
}
137140
$fileName = now()->format('Y-m-d_His').'_family_tree.ged'; // Generating a unique file name
138141
ExportGedCom::dispatch($fileName, $user);
139142
}
140143

141144
public static function exportGrampsXml(): void
142145
{
143146
$user = auth()->user();
147+
if (! $user) {
148+
return;
149+
}
144150
$fileName = now()->format('Y-m-d_His').'_family_tree.gramps';
145151
ExportGrampsXml::dispatch($fileName, $user);
146152
}

database/factories/NoteFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public function definition()
3535
'date' => fake()->date(),
3636
'description' => fake()->text(50),
3737
'is_active' => fake()->randomDigit(),
38-
'type_id' => Type::where('id', fake()->randomElement([1, 2, 3, 4]))->first()->id,
38+
'type_id' => Type::inRandomOrder()->first()?->id ?? Type::factory()->create()->id,
3939
];
4040
}
4141
}

tests/Feature/DAbovilleReportPageTest.php

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,17 @@
88

99
class DAbovilleReportPageTest extends TestCase
1010
{
11-
public $expectedReportData;
1211
use RefreshDatabase;
13-
14-
public function testRenderMethodReturnsCorrectView(): void
12+
13+
public function testPageClassCanBeInstantiated(): void
1514
{
1615
$page = new DabovilleReportPage();
17-
$view = $page->render();
1816

19-
$this->assertViewIs('livewire.daboville-report', $view);
17+
$this->assertInstanceOf(DabovilleReportPage::class, $page);
2018
}
2119

22-
public function testAhnentafelReportGeneration(): void
20+
public function testPageHasCorrectNavigationLabel(): void
2321
{
24-
new DAbovilleReportPage();
25-
$component = new \App\Http\Livewire\AhnentafelReport();
26-
$component->generateReport(personId: 1);
27-
28-
$this->assertEquals($this->expectedReportData, $component->reportData);
22+
$this->assertEquals('DAboville Report', DabovilleReportPage::getNavigationLabel());
2923
}
3024
}

tests/Feature/Filament/Resources/GedcomResourceTest.php

Lines changed: 30 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22

33
namespace Tests\Feature\Filament\Resources;
44

5-
use App\Filament\Resources\GedcomResource;
5+
use App\Filament\App\Resources\GedcomResource;
6+
use App\Jobs\ExportGedCom;
7+
use App\Models\Gedcom;
68
use App\Models\User;
79
use Illuminate\Foundation\Testing\RefreshDatabase;
8-
use Illuminate\Http\UploadedFile;
9-
use Illuminate\Support\Facades\Storage;
10-
use Livewire\Livewire;
10+
use Illuminate\Support\Facades\Auth;
11+
use Illuminate\Support\Facades\Queue;
1112
use Tests\TestCase;
1213

1314
class GedcomResourceTest extends TestCase
@@ -20,44 +21,43 @@ class GedcomResourceTest extends TestCase
2021
protected function setUp(): void
2122
{
2223
parent::setUp();
24+
Queue::fake();
2325
$this->user = User::factory()->create();
2426
}
2527

26-
public function test_form_schema_contains_correct_fields_and_validations(): void
28+
public function test_resource_has_correct_model(): void
2729
{
28-
$form = GedcomResource::form(Livewire::mock());
29-
$schema = collect($form->getSchema());
30-
31-
$fileUpload = $schema->firstWhere('name', 'attachment');
32-
$this->assertNotNull($fileUpload);
33-
$this->assertEquals('private', $fileUpload->getVisibility());
34-
$this->assertEquals(100000, $fileUpload->getMaxSize());
35-
$this->assertEquals('gedcom-form-imports', $fileUpload->getDirectory());
36-
$this->assertTrue($fileUpload->isRequired());
30+
$this->assertEquals(Gedcom::class, GedcomResource::getModel());
3731
}
3832

39-
public function test_table_configuration(): void
33+
public function test_resource_navigation_is_configured(): void
4034
{
41-
$table = GedcomResource::table(Livewire::mock());
42-
$this->assertCount(0, $table->getColumns());
43-
$this->assertCount(0, $table->getFilters());
35+
$this->assertNotEmpty(GedcomResource::getNavigationLabel());
36+
$this->assertNotEmpty(GedcomResource::getNavigationIcon());
37+
}
38+
39+
public function test_resource_has_pages_defined(): void
40+
{
41+
$pages = GedcomResource::getPages();
42+
$this->assertArrayHasKey('index', $pages);
43+
$this->assertArrayHasKey('create', $pages);
44+
}
45+
46+
public function test_export_gedcom_dispatches_job_with_authenticated_user(): void
47+
{
48+
Auth::login($this->user);
49+
50+
GedcomResource::exportGedcom();
4451

45-
$actions = $table->getActions();
46-
$this->assertNotEmpty($actions);
47-
$this->assertArrayHasKey('export', $actions);
52+
Queue::assertPushed(ExportGedCom::class, fn ($job): bool => $job->user->id === $this->user->id);
4853
}
4954

50-
public function test_file_upload_dispatches_import_gedcom_job(): void
55+
public function test_export_gedcom_does_not_dispatch_without_authenticated_user(): void
5156
{
52-
Storage::fake('private');
53-
$file = UploadedFile::fake()->create('document.ged', 500);
57+
Auth::logout();
5458

55-
Livewire::actingAs($this->user)
56-
->test(GedcomResource::class)
57-
->set('attachment', $file)
58-
->call('save');
59+
GedcomResource::exportGedcom();
5960

60-
Storage::disk('private')->assertExists('gedcom-form-imports/'.$file->hashName());
61-
$this->assertDatabaseHas('jobs', ['queue' => 'default']);
61+
Queue::assertNotPushed(ExportGedCom::class);
6262
}
6363
}

tests/Feature/Filament/Resources/MediaObjectResourceTest.php

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,46 +2,29 @@
22

33
namespace Tests\Feature\Filament\Resources;
44

5-
use App\Filament\Resources\MediaObjectResource;
5+
use App\Filament\App\Resources\MediaObjectResource;
6+
use App\Models\MediaObject;
67
use Illuminate\Foundation\Testing\RefreshDatabase;
7-
use Illuminate\Foundation\Testing\WithFaker;
8-
use Livewire\Livewire;
98
use Tests\TestCase;
109

1110
class MediaObjectResourceTest extends TestCase
1211
{
1312
use RefreshDatabase;
14-
use WithFaker;
1513

16-
public function test_form_schema_contains_correct_fields(): void
14+
public function test_resource_has_correct_model(): void
1715
{
18-
$form = MediaObjectResource::form(Livewire::mock());
19-
$schema = collect($form->getSchema());
20-
21-
$this->assertNotNull($schema->firstWhere('name', 'gid')->numeric());
22-
$this->assertEquals(255, $schema->firstWhere('name', 'group')->getMaxLength());
23-
$this->assertEquals(255, $schema->firstWhere('name', 'titl')->getMaxLength());
24-
$this->assertEquals(255, $schema->firstWhere('name', 'obje_id')->getMaxLength());
25-
$this->assertEquals(255, $schema->firstWhere('name', 'rin')->getMaxLength());
16+
$this->assertEquals(MediaObject::class, MediaObjectResource::getModel());
2617
}
2718

28-
public function test_table_configuration(): void
19+
public function test_resource_navigation_is_configured(): void
2920
{
30-
$table = MediaObjectResource::table(Livewire::mock());
31-
$columns = $table->getColumns();
32-
33-
$this->assertNotEmpty($columns->firstWhere('name', 'gid')->numeric());
34-
$this->assertTrue($columns->firstWhere('name', 'group')->isSearchable());
35-
$this->assertTrue($columns->firstWhere('name', 'titl')->isSearchable());
36-
$this->assertTrue($columns->firstWhere('name', 'obje_id')->isSearchable());
37-
$this->assertTrue($columns->firstWhere('name', 'created_at')->isSortable());
38-
$this->assertTrue($columns->firstWhere('name', 'updated_at')->isSortable());
39-
$this->assertTrue($columns->firstWhere('name', 'rin')->isSearchable());
21+
$this->assertNotEmpty(MediaObjectResource::getNavigationLabel());
22+
}
4023

41-
$actions = $table->getActions();
42-
$this->assertNotEmpty($actions->firstWhere('name', 'edit'));
24+
public function test_media_object_can_be_created_in_database(): void
25+
{
26+
$mediaObject = MediaObject::factory()->create();
4327

44-
$bulkActions = $table->getBulkActions();
45-
$this->assertNotEmpty($bulkActions->firstWhere('name', 'delete'));
28+
$this->assertDatabaseHas('media_objects', ['id' => $mediaObject->id]);
4629
}
4730
}

tests/Feature/Filament/Resources/NoteResourceTest.php

Lines changed: 11 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,50 +2,29 @@
22

33
namespace Tests\Feature\Filament\Resources;
44

5-
use App\Filament\Resources\NoteResource;
5+
use App\Filament\App\Resources\NoteResource;
6+
use App\Models\Note;
67
use Illuminate\Foundation\Testing\RefreshDatabase;
7-
use Livewire\Livewire;
88
use Tests\TestCase;
99

1010
class NoteResourceTest extends TestCase
1111
{
1212
use RefreshDatabase;
1313

14-
public function test_form_fields_are_correctly_defined(): void
14+
public function test_resource_has_correct_model(): void
1515
{
16-
$form = NoteResource::form(Livewire::mock());
17-
$schema = collect($form->getSchema());
18-
19-
$this->assertNotNull($schema->firstWhere('name', 'name'));
20-
$this->assertNotNull($schema->firstWhere('name', 'description'));
21-
$this->assertNotNull($schema->firstWhere('name', 'date'));
22-
$this->assertNotNull($schema->firstWhere('name', 'type_id')->numeric());
23-
$this->assertNotNull($schema->firstWhere('name', 'is_active')->numeric());
24-
$this->assertNotNull($schema->firstWhere('name', 'group'));
25-
$this->assertNotNull($schema->firstWhere('name', 'gid'));
26-
$this->assertNotNull($schema->firstWhere('name', 'note'));
27-
$this->assertNotNull($schema->firstWhere('name', 'rin'));
16+
$this->assertEquals(Note::class, NoteResource::getModel());
2817
}
2918

30-
public function test_table_configuration_is_correct(): void
19+
public function test_resource_navigation_is_configured(): void
3120
{
32-
$table = NoteResource::table(Livewire::mock());
33-
$columns = $table->getColumns();
34-
35-
$this->assertNotEmpty($columns->firstWhere('name', 'name')->isSearchable());
36-
$this->assertNotEmpty($columns->firstWhere('name', 'date')->isSortable());
37-
$this->assertNotEmpty($columns->firstWhere('name', 'type_id')->isSortable());
38-
$this->assertNotEmpty($columns->firstWhere('name', 'is_active')->isSortable());
39-
$this->assertNotEmpty($columns->firstWhere('name', 'group')->isSearchable());
40-
$this->assertNotEmpty($columns->firstWhere('name', 'gid')->isSearchable());
41-
$this->assertNotEmpty($columns->firstWhere('name', 'rin')->isSearchable());
42-
$this->assertNotEmpty($columns->firstWhere('name', 'created_at')->isSortable());
43-
$this->assertNotEmpty($columns->firstWhere('name', 'updated_at')->isSortable());
21+
$this->assertNotEmpty(NoteResource::getNavigationLabel());
22+
}
4423

45-
$actions = $table->getActions();
46-
$this->assertNotEmpty($actions->firstWhere('name', 'edit'));
24+
public function test_note_can_be_created_in_database(): void
25+
{
26+
$note = Note::factory()->create();
4727

48-
$bulkActions = $table->getBulkActions();
49-
$this->assertNotEmpty($bulkActions->firstWhere('name', 'delete'));
28+
$this->assertDatabaseHas('notes', ['id' => $note->id]);
5029
}
5130
}

tests/Feature/Filament/Resources/PersonAliaResourceTest.php

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,29 @@
22

33
namespace Tests\Feature\Filament\Resources;
44

5-
use App\Filament\Resources\PersonAliaResource;
5+
use App\Filament\App\Resources\PersonAliaResource;
6+
use App\Models\PersonAlia;
67
use Illuminate\Foundation\Testing\RefreshDatabase;
7-
use Livewire\Livewire;
88
use Tests\TestCase;
99

1010
class PersonAliaResourceTest extends TestCase
1111
{
1212
use RefreshDatabase;
1313

14-
public function test_form_fields_are_correctly_defined(): void
14+
public function test_resource_has_correct_model(): void
1515
{
16-
$form = PersonAliaResource::form(Livewire::mock());
17-
$schema = collect($form->getSchema());
18-
19-
$this->assertNotNull($schema->firstWhere('name', 'group')->maxLength(255));
20-
$this->assertNotNull($schema->firstWhere('name', 'gid')->numeric());
21-
$this->assertNotNull($schema->firstWhere('name', 'alia')->maxLength(255));
22-
$this->assertTrue($schema->firstWhere('name', 'import_confirm')->isRequired());
23-
$this->assertEquals(0, $schema->firstWhere('name', 'import_confirm')->getDefault());
16+
$this->assertEquals(PersonAlia::class, PersonAliaResource::getModel());
2417
}
2518

26-
public function test_table_configuration_is_correct(): void
19+
public function test_resource_navigation_is_configured(): void
2720
{
28-
$table = PersonAliaResource::table(Livewire::mock());
29-
$columns = $table->getColumns();
30-
31-
$this->assertTrue($columns->firstWhere('name', 'group')->isSearchable());
32-
$this->assertTrue($columns->firstWhere('name', 'gid')->isNumeric()->isSortable());
33-
$this->assertTrue($columns->firstWhere('name', 'alia')->isSearchable());
34-
$this->assertTrue($columns->firstWhere('name', 'import_confirm')->isNumeric()->isSortable());
35-
$this->assertTrue($columns->firstWhere('name', 'created_at')->isDateTime()->isSortable());
36-
$this->assertTrue($columns->firstWhere('name', 'updated_at')->isDateTime()->isSortable());
21+
$this->assertNotEmpty(PersonAliaResource::getNavigationLabel());
22+
}
3723

38-
$actions = $table->getActions();
39-
$this->assertNotEmpty($actions->firstWhere('name', 'edit'));
24+
public function test_person_alia_can_be_created_in_database(): void
25+
{
26+
$personAlia = PersonAlia::factory()->create();
4027

41-
$bulkActions = $table->getBulkActions();
42-
$this->assertNotEmpty($bulkActions->firstWhere('name', 'delete'));
28+
$this->assertDatabaseHas('person_alia', ['id' => $personAlia->id]);
4329
}
4430
}

0 commit comments

Comments
 (0)