createUser(['ROLE_CLINIC']); $res = $this->authJson('GET', '/api/v1/my/payment-methods/bank-accounts', $user); $this->assertSame(200, $this->responseCode()); $this->assertTrue($res['success']); $this->assertSame([], $res['data']); } public function testCreateAndListBankAccount(): void { $user = $this->createUser(['ROLE_CLINIC']); $created = $this->authJson('POST', '/api/v1/my/payment-methods/bank-accounts', $user, [ 'bank_name' => 'ملی', 'card_number' => '6037991234567890', 'account_number' => '0101234567890', 'shaba_number' => 'IR820540102680020817909002', ]); $this->assertSame(201, $this->responseCode()); $this->assertSame('ملی', $created['data']['bank_name']); $this->assertTrue($created['data']['is_active']); $this->assertNotEmpty($created['data']['uuid']); $list = $this->authJson('GET', '/api/v1/my/payment-methods/bank-accounts', $user); $this->assertCount(1, $list['data']); $this->assertSame('0101234567890', $list['data'][0]['account_number']); } public function testCreateBankAccountValidationErrorWhenBankNameMissing(): void { $user = $this->createUser(['ROLE_CLINIC']); $res = $this->authJson('POST', '/api/v1/my/payment-methods/bank-accounts', $user, [ 'account_number' => '0101234567890', ]); $this->assertSame(422, $this->responseCode()); $this->assertFalse($res['success']); $this->assertSame('bank_name', $res['errors'][0]['field']); } public function testUpdateBankAccount(): void { $user = $this->createUser(['ROLE_CLINIC']); $created = $this->authJson('POST', '/api/v1/my/payment-methods/bank-accounts', $user, [ 'bank_name' => 'ملی', 'account_number' => '0101234567890', ]); $uuid = $created['data']['uuid']; $updated = $this->authJson('PUT', "/api/v1/my/payment-methods/bank-accounts/$uuid", $user, [ 'bank_name' => 'ملت', 'account_number' => '0209876543210', ]); $this->assertSame(200, $this->responseCode()); $this->assertSame('ملت', $updated['data']['bank_name']); $this->assertSame('0209876543210', $updated['data']['account_number']); } public function testToggleBankAccountStatus(): void { $user = $this->createUser(['ROLE_CLINIC']); $created = $this->authJson('POST', '/api/v1/my/payment-methods/bank-accounts', $user, [ 'bank_name' => 'ملی', 'account_number' => '0101234567890', ]); $uuid = $created['data']['uuid']; $this->assertTrue($created['data']['is_active']); $toggled = $this->authJson('PATCH', "/api/v1/my/payment-methods/bank-accounts/$uuid/status", $user); $this->assertSame(200, $this->responseCode()); $this->assertFalse($toggled['data']['is_active']); } public function testToggleUnknownBankAccountReturns404(): void { $user = $this->createUser(['ROLE_CLINIC']); $res = $this->authJson('PATCH', '/api/v1/my/payment-methods/bank-accounts/does-not-exist/status', $user); $this->assertSame(404, $this->responseCode()); $this->assertFalse($res['success']); } public function testCannotTouchAnotherClinicsBankAccount(): void { $owner = $this->createUser(['ROLE_CLINIC']); $other = $this->createUser(['ROLE_CLINIC']); $created = $this->authJson('POST', '/api/v1/my/payment-methods/bank-accounts', $owner, [ 'bank_name' => 'ملی', 'account_number' => '0101234567890', ]); $uuid = $created['data']['uuid']; $res = $this->authJson('PATCH', "/api/v1/my/payment-methods/bank-accounts/$uuid/status", $other); $this->assertSame(404, $this->responseCode()); $this->assertFalse($res['success']); } public function testBankAccountForbiddenForPlainUser(): void { $user = $this->createUser(['ROLE_USER']); $this->authJson('GET', '/api/v1/my/payment-methods/bank-accounts', $user); $this->assertSame(403, $this->responseCode()); } // ---- POS devices ------------------------------------------------------- public function testCreateAndListPos(): void { $user = $this->createUser(['ROLE_DOCTOR']); $created = $this->authJson('POST', '/api/v1/my/payment-methods/pos', $user, [ 'bank_name' => 'ملت', 'serial_number' => 'SN-98765', 'terminal_number' => '123456', ]); $this->assertSame(201, $this->responseCode()); $this->assertSame('ملت', $created['data']['bank_name']); $this->assertSame('123456', $created['data']['terminal_number']); $this->assertTrue($created['data']['is_active']); $list = $this->authJson('GET', '/api/v1/my/payment-methods/pos', $user); $this->assertCount(1, $list['data']); } public function testCreatePosValidationErrorWhenTerminalMissing(): void { $user = $this->createUser(['ROLE_DOCTOR']); $res = $this->authJson('POST', '/api/v1/my/payment-methods/pos', $user, [ 'bank_name' => 'ملت', ]); $this->assertSame(422, $this->responseCode()); $this->assertSame('terminal_number', $res['errors'][0]['field']); } public function testTogglePosStatus(): void { // منشی به روش‌های پرداخت فقط با مجوز payments از طریق رابطهٔ فعال دسترسی دارد. $user = $this->createSecretaryWithPayments(['view' => true, 'create' => true, 'update' => true]); $created = $this->authJson('POST', '/api/v1/my/payment-methods/pos', $user, [ 'bank_name' => 'تجارت', 'terminal_number' => '345678', ]); $uuid = $created['data']['uuid']; $toggled = $this->authJson('PATCH', "/api/v1/my/payment-methods/pos/$uuid/status", $user); $this->assertSame(200, $this->responseCode()); $this->assertFalse($toggled['data']['is_active']); } public function testSecretaryWithoutPaymentsPermissionCannotManagePos(): void { $user = $this->createSecretaryWithPayments(['view' => false, 'create' => false, 'update' => false]); $this->authJson('POST', '/api/v1/my/payment-methods/pos', $user, [ 'bank_name' => 'تجارت', 'terminal_number' => '345678', ]); $this->assertSame(403, $this->responseCode()); } /** منشی با رابطهٔ فعالِ کلینیک + context + مجوز payments مشخص. */ private function createSecretaryWithPayments(array $payments): \App\Auth\Entity\User { $owner = $this->createUser(['ROLE_CLINIC']); $clinic = new \App\Clinic\Entity\Clinic($owner); $this->em->persist($clinic); $doctor = new \App\Doctor\Entity\Doctor($this->createUser(['ROLE_DOCTOR']), 'دکتر تست'); $this->em->persist($doctor); $clinic->getDoctors()->add($doctor); $secretary = $this->createUser(['ROLE_SECRETARY']); $rel = new \App\Secretary\Entity\DoctorSecretary($doctor, $secretary, $clinic); $rel->mergePermissions(['resources' => ['payments' => $payments]]); $this->em->persist($rel); $this->em->persist(new \App\Auth\Entity\UserActiveContext( $secretary, $clinic->getUuid(), \App\Shared\Context\EntityContext::TYPE_CLINIC, )); $this->em->flush(); return $secretary; } public function testPosListIsolatedPerUser(): void { $a = $this->createUser(['ROLE_CLINIC']); $b = $this->createUser(['ROLE_CLINIC']); $this->authJson('POST', '/api/v1/my/payment-methods/pos', $a, [ 'bank_name' => 'صادرات', 'terminal_number' => '901234', ]); $listB = $this->authJson('GET', '/api/v1/my/payment-methods/pos', $b); $this->assertSame([], $listB['data']); } }