2026-06-14 21:32:07 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
|
|
use App\Exceptions\GlobalHandler;
|
2026-10-02 12:14:48 +02:00
|
|
|
use App\Services\ArcadiaEmployee;
|
|
|
|
|
use App\Services\EmployeeSyncServiceResult;
|
2026-06-14 21:32:07 +02:00
|
|
|
use Symfony\Component\Finder\Finder;
|
|
|
|
|
|
|
|
|
|
describe('naming conventions in app', function (): void {
|
|
|
|
|
arch('casts have Cast suffix')
|
|
|
|
|
->expect("App\Cast")
|
|
|
|
|
->toHaveSuffix('Cast');
|
|
|
|
|
|
|
|
|
|
arch('adapters repositories have Repository suffix')
|
|
|
|
|
->expect("App\Adapters\Repositories")
|
|
|
|
|
->toHaveSuffix('Repository');
|
|
|
|
|
|
|
|
|
|
arch('dtos have Dto suffix')
|
|
|
|
|
->expect("App\Dtos")
|
|
|
|
|
->toHaveSuffix('Dto');
|
|
|
|
|
|
|
|
|
|
arch('exceptions have Exception suffix')
|
|
|
|
|
->expect("App\Exceptions")
|
|
|
|
|
->toHaveSuffix('Exception')
|
|
|
|
|
->ignoring([
|
|
|
|
|
GlobalHandler::class,
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
arch('controllers have Controller suffix')
|
|
|
|
|
->expect("App\Http\Controllers")
|
|
|
|
|
->toHaveSuffix('Controller');
|
|
|
|
|
|
|
|
|
|
arch('requests have Request suffix')
|
|
|
|
|
->expect("App\Http\Requests")
|
|
|
|
|
->toHaveSuffix('Request');
|
|
|
|
|
|
|
|
|
|
arch('resources have Resource suffix')
|
|
|
|
|
->expect("App\Http\Resources")
|
|
|
|
|
->toHaveSuffix('Resource');
|
|
|
|
|
|
|
|
|
|
arch('policies have Policy suffix')
|
|
|
|
|
->expect("App\Policies")
|
|
|
|
|
->toHaveSuffix('Policy');
|
|
|
|
|
|
|
|
|
|
arch('providers have Provider suffix')
|
|
|
|
|
->expect("App\Providers")
|
|
|
|
|
->toHaveSuffix('Provider');
|
|
|
|
|
|
|
|
|
|
arch('services have Service suffix')
|
|
|
|
|
->expect("App\Services")
|
feat(employees): automated sync with Arcadia API, BO settings, Shopper value objects, and pagination migration
- Implement automated synchronization of employees via Arcadia API (EmployeeSyncService, SynchronizeEmployeesWithArcadiaApi, FetchAndUpsertArcadiaEmployees)
- Add Back-Office application settings for employee sites (Setting singleton, GetSettingsQuery, UpdateSettings, SettingsController, EmployeeSitesInputComponent.vue)
- Strongly type Employee attributes using Domain Value Objects (ShopperEstablishmentCode, ShopperSiteCode, ShopperServiceCode) and Eloquent Casts
- Migrate pagination from Domain to Shared\Pagination namespace across queries and inputs
- Remove legacy and dead CSV employee import/export code
- Restore Domain\Ports\Services\CsvGenerator interface for Regate order generation
- Add comprehensive Pest unit, integration, and feature test coverage
2026-10-01 17:26:30 +02:00
|
|
|
->toHaveSuffix('Service')
|
|
|
|
|
->ignoring([
|
2026-10-02 12:14:48 +02:00
|
|
|
ArcadiaEmployee::class,
|
|
|
|
|
EmployeeSyncServiceResult::class,
|
feat(employees): automated sync with Arcadia API, BO settings, Shopper value objects, and pagination migration
- Implement automated synchronization of employees via Arcadia API (EmployeeSyncService, SynchronizeEmployeesWithArcadiaApi, FetchAndUpsertArcadiaEmployees)
- Add Back-Office application settings for employee sites (Setting singleton, GetSettingsQuery, UpdateSettings, SettingsController, EmployeeSitesInputComponent.vue)
- Strongly type Employee attributes using Domain Value Objects (ShopperEstablishmentCode, ShopperSiteCode, ShopperServiceCode) and Eloquent Casts
- Migrate pagination from Domain to Shared\Pagination namespace across queries and inputs
- Remove legacy and dead CSV employee import/export code
- Restore Domain\Ports\Services\CsvGenerator interface for Regate order generation
- Add comprehensive Pest unit, integration, and feature test coverage
2026-10-01 17:26:30 +02:00
|
|
|
]);
|
2026-09-29 13:03:19 +02:00
|
|
|
|
2026-09-30 10:59:33 +02:00
|
|
|
arch('queries have Query, QueryInput or QueryOutput suffix', function (): void {
|
|
|
|
|
$path = __DIR__ . '/../../app/Queries';
|
|
|
|
|
$files = (new Finder())->files()->in($path)->name('*.php');
|
|
|
|
|
|
|
|
|
|
foreach ($files as $file) {
|
|
|
|
|
$className = $file->getBasename('.php');
|
|
|
|
|
expect(
|
|
|
|
|
str_ends_with($className, 'Query')
|
|
|
|
|
|| str_ends_with($className, 'QueryInput')
|
|
|
|
|
|| str_ends_with($className, 'QueryOutput')
|
|
|
|
|
)->toBeTrue("{$className} must have suffix Query, QueryInput or QueryOutput");
|
|
|
|
|
}
|
|
|
|
|
});
|
2026-06-14 21:32:07 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('naming conventions in domain', function (): void {
|
|
|
|
|
|
|
|
|
|
arch('dtos have Dto suffix')
|
|
|
|
|
->expect("Domain\Dto")
|
|
|
|
|
->toHaveSuffix('Dto');
|
|
|
|
|
|
|
|
|
|
arch('exceptions have Exception suffix')
|
|
|
|
|
->expect("Domain\Exceptions")
|
|
|
|
|
->toHaveSuffix('Exception');
|
|
|
|
|
|
|
|
|
|
arch('policies have Policy suffix')
|
|
|
|
|
->expect("Domain\Policies")
|
|
|
|
|
->toHaveSuffix('Policy');
|
|
|
|
|
|
|
|
|
|
arch('port directories have Directory suffix')
|
|
|
|
|
->expect("Domain\Ports\Directories")
|
|
|
|
|
->toHaveSuffix('Directory');
|
|
|
|
|
|
|
|
|
|
arch('port repositories have Repository suffix')
|
|
|
|
|
->expect("Domain\Ports\Repositories")
|
|
|
|
|
->toHaveSuffix('Repository');
|
|
|
|
|
|
|
|
|
|
arch('domain services have Service suffix')
|
|
|
|
|
->expect("Domain\Services")
|
|
|
|
|
->toHaveSuffix('Service');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
describe('naming conventions in infrastructure', function (): void {
|
|
|
|
|
arch('adapters implement an interface from their domain ports', function (string $folder, string $infraNs, string $domainNs): void {
|
|
|
|
|
$path = __DIR__ . '/../../infra/' . $folder;
|
|
|
|
|
$files = (new Finder())->files()->in($path)->name('*.php');
|
|
|
|
|
|
|
|
|
|
foreach ($files as $file) {
|
|
|
|
|
$className = $infraNs . '\\' . $file->getFilenameWithoutExtension();
|
|
|
|
|
$interfaces = (new \ReflectionClass($className))->getInterfaceNames();
|
|
|
|
|
$hasDomainPort = ! empty(array_filter(
|
|
|
|
|
$interfaces,
|
|
|
|
|
fn ($interface) => str_starts_with($interface, $domainNs)
|
|
|
|
|
));
|
|
|
|
|
|
|
|
|
|
expect($hasDomainPort)
|
|
|
|
|
->toBeTrue(message: "La classe {$className} n'implémente aucune interface de {$domainNs}.");
|
|
|
|
|
}
|
|
|
|
|
})->with([
|
|
|
|
|
'Directories' => ['Adapters/Directories', 'Infrastructure\Adapters\Directories', 'Domain\Ports\Directories\\'],
|
|
|
|
|
'Repositories' => ['Adapters/Repositories', 'Infrastructure\Adapters\Repositories', 'Domain\Ports\Repositories\\'],
|
|
|
|
|
'Services' => ['Adapters/Services', 'Infrastructure\Adapters\Services', 'Domain\Ports\Services\\'],
|
|
|
|
|
]);
|
|
|
|
|
});
|