Refactor doctor data repair commands into a single command
- Removed individual commands for backfilling specialty parents, surrogate roles, and fixing IRIMC names. - Introduced RepairImportedDoctorsCommand to consolidate functionality. - Implemented a step-based approach for repairs, allowing for idempotent execution. - Added new service classes for handling specific repair steps, including BackfillSpecialtyParentsStep, BackfillSurrogateRoleStep, FixDegreeStep, and StripNameTitleStep. - Created RepairOptions and RepairResult classes to manage step execution options and results. - Updated tests to ensure new command structure and functionality are covered, including idempotency and dry-run behavior. - Added IrimcDegreeMapper for mapping IRIMC titles to degrees.
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace App\Tests\Doctor;
|
||||
|
||||
use App\Doctor\Entity\Doctor;
|
||||
use App\Doctor\Service\IrimcDegreeMapper;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
/**
|
||||
* تا ۱۴۰۵/۰۴/۲۸ خزندهٔ irimc دو کد را جابهجا میفرستاد: «فوق تخصص» را specialist
|
||||
* (برچسب: متخصص) و «تخصص» را expert (برچسب: فوق تخصص). نتیجهاش ۱۸۸۵ پزشک با درجهٔ
|
||||
* غلط بود — مثلاً «تخصص جراحی استخوان و مفاصل (ارتوپدی)» که «فوق تخصص» نمایش میداد.
|
||||
*
|
||||
* این تست قرارداد نگاشت را قفل میکند تا جابهجایی دوباره اتفاق نیفتد.
|
||||
*/
|
||||
class IrimcDegreeMappingTest extends TestCase
|
||||
{
|
||||
#[DataProvider('titles')]
|
||||
public function testDegreeFromIrimcTitle(?string $title, ?string $expected): void
|
||||
{
|
||||
$this->assertSame($expected, IrimcDegreeMapper::fromTitle($title));
|
||||
}
|
||||
|
||||
public static function titles(): array
|
||||
{
|
||||
return [
|
||||
// همان رکوردی که باگ را لو داد (پزشک #2269)
|
||||
'takhasos with general doctorate' => [
|
||||
'تخصص جراحی استخوان و مفاصل (ارتوپدی) دکترای حرفهای پزشکی',
|
||||
'specialist',
|
||||
],
|
||||
'plain takhasos' => ['تخصص بیماریهای داخلی', 'specialist'],
|
||||
'motakhases' => ['متخصص زنان و زایمان', 'specialist'],
|
||||
|
||||
// «فوق تخصص» شامل «تخصص» است — ترتیب شرطها باید این را درست بگیرد
|
||||
'fogh takhasos' => ['فوق تخصص جراحی قلب و عروق', 'expert'],
|
||||
'fogh takhasos zwnj' => ['فوقتخصص گوارش و کبد بالغین', 'expert'],
|
||||
|
||||
// فلوشیپ بر همه مقدم است، حتی وقتی کنارش «تخصص» آمده
|
||||
'fellowship' => ['فلوشیپ اکوکاردیوگرافی', 'subspecialistplus'],
|
||||
'fellowship w/ takh' => ['فلوشیپ جراحی، تخصص چشمپزشکی', 'subspecialistplus'],
|
||||
|
||||
// عمومی فقط وقتی هیچ تخصصی در عنوان نیست
|
||||
'general doctorate' => ['دکترای حرفهای پزشکی', 'general'],
|
||||
'general physician' => ['پزشک عمومی', 'general'],
|
||||
|
||||
// ناشناخته/خالی → null؛ درجهٔ غلط از نبودِ درجه بدتر است
|
||||
'unknown' => ['کارشناس تغذیه', null],
|
||||
'empty' => ['', null],
|
||||
'whitespace' => [' ', null],
|
||||
'null' => [null, null],
|
||||
];
|
||||
}
|
||||
|
||||
#[DataProvider('titles')]
|
||||
public function testMappedDegreeIsAlwaysAValidEntityDegree(?string $title, ?string $expected): void
|
||||
{
|
||||
$degree = IrimcDegreeMapper::fromTitle($title);
|
||||
|
||||
if ($degree !== null) {
|
||||
$this->assertContains($degree, Doctor::DEGREES);
|
||||
}
|
||||
$this->assertSame($expected, $degree);
|
||||
}
|
||||
|
||||
public function testLabelsMatchTheAdminPanelWording(): void
|
||||
{
|
||||
// اگر اینها با DoctorDetailPage.tsx (DEGREE_LABELS) فرق کنند، دوباره
|
||||
// همان باگ «تخصص ↔ فوق تخصص» برمیگردد، اینبار در لایهٔ نمایش.
|
||||
$this->assertSame('متخصص', IrimcDegreeMapper::label('specialist'));
|
||||
$this->assertSame('فوق تخصص', IrimcDegreeMapper::label('expert'));
|
||||
$this->assertSame('عمومی', IrimcDegreeMapper::label('general'));
|
||||
$this->assertSame('فلوشیپ', IrimcDegreeMapper::label('subspecialistplus'));
|
||||
}
|
||||
|
||||
public function testEveryLabelKeyIsAKnownEntityDegree(): void
|
||||
{
|
||||
foreach (array_keys(IrimcDegreeMapper::LABELS) as $degree) {
|
||||
$this->assertTrue(IrimcDegreeMapper::isValid($degree), "«$degree» در Doctor::DEGREES نیست");
|
||||
}
|
||||
$this->assertFalse(IrimcDegreeMapper::isValid('nonsense'));
|
||||
$this->assertFalse(IrimcDegreeMapper::isValid(null));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user