createUser(['ROLE_USER', 'ROLE_DOCTOR']); $doctor = new Doctor($owner, 'دکتر تست'); $this->em->persist($doctor); $this->em->flush(); // db_test پاک نمی‌شود؛ شماره باید تازه باشد وگرنه endpoint با «تکراری» رد می‌کند. do { $persianMobile = '۰۹' . str_pad((string) random_int(0, 999_999_999), 9, '۰', STR_PAD_LEFT); $latinMobile = PersianText::digits($persianMobile); } while ($this->em->getRepository(User::class)->findOneBy(['mobileNumber' => $latinMobile]) !== null); // کد ملی هم همین‌طور. ثابت‌بودنش این تست را flaky می‌کرد: در اجرای کامل سوئیت، // بسته به ترتیب اجرا، ردیفِ اجرای قبلی باعث ۴۲۲ «تکراری» می‌شد و در اجرای تنها // سبز بود. // مثل شماره، یکتایی‌اش هم باید سنجیده شود: تصادفی‌بودن تنهایی کافی نیست و در // اجرای کامل سوئیت روی db_testِ انباشته، برخورد ۴۲۲ «تکراری» می‌داد. do { $persianNationalCode = str_pad( $this->toPersianDigits((string) random_int(0, 9_999_999_999)), 10, '۰', STR_PAD_LEFT, ); $latinNationalCode = PersianText::digits($persianNationalCode); } while ( $this->em->getRepository(DoctorSecretary::class) ->findOneBy(['nationalCode' => $latinNationalCode]) !== null ); $body = $this->authJson('POST', '/api/v1/secretary', $owner, [ 'doctor_uuid' => $doctor->getUuid(), 'mobile_number' => $persianMobile, 'name' => 'منشی تست', 'national_code' => $persianNationalCode, ]); // بدنه در پیام می‌آید: «۴۲۲ به‌جای ۲۰۱» بدون دلیلِ سرور قابل دیباگ نیست. self::assertSame( 201, $this->responseCode(), 'Persian digits must not break validation: ' . json_encode($body, JSON_UNESCAPED_UNICODE), ); $this->em->clear(); $created = $this->em->getRepository(User::class)->findOneBy(['mobileNumber' => $latinMobile]); self::assertNotNull($created, 'user is stored under the latin mobile'); $rel = $this->em->getRepository(DoctorSecretary::class)->findOneBy(['secretary' => $created]); self::assertSame(PersianText::digits($persianNationalCode), $rel->getNationalCode()); } public function testNestedArraysAreNormalized(): void { $user = $this->createUser(['ROLE_USER', 'ROLE_DOCTOR']); $this->authJson('PUT', '/api/v1/insurance-pricing', $user, [ 'free_visit_price_rials' => '۵۰۰۰۰۰', 'insurances' => [ ['insurance_id' => 1, 'patient_share_rials' => '۱۲۳۴۵'], ], ]); // پروفایل پزشک ممکن است بیمه‌ای نداشته باشد؛ مهم این است که ارقام فارسی // باعث خطای اعتبارسنجی یا NaN نشوند. self::assertNotSame(500, $this->responseCode(), 'nested persian digits must not blow up'); } public function testNonNumericKeysKeepPersianDigits(): void { $owner = $this->createUser(['ROLE_USER', 'ROLE_DOCTOR']); $doctor = new Doctor($owner, 'دکتر تست'); $this->em->persist($doctor); $this->em->flush(); $mobile = '09' . str_pad((string) random_int(0, 999_999_999), 9, '0', STR_PAD_LEFT); $this->authJson('POST', '/api/v1/secretary', $owner, [ 'doctor_uuid' => $doctor->getUuid(), 'mobile_number' => $mobile, 'name' => 'منشی شماره ۲', ]); self::assertSame(201, $this->responseCode()); $this->em->clear(); $created = $this->em->getRepository(User::class)->findOneBy(['mobileNumber' => $mobile]); self::assertStringContainsString('۲', $created->getRealName(), 'name is not a numeric field'); } }