/** * Descomplicar® Crescimento Digital * https://descomplicar.pt */ markTestIncomplete( 'Prescriptions POST endpoint not implemented yet - TDD RED phase' ); // ARRANGE: Valid prescription data $clinic_id = $this->create_test_clinic(); $appointment_id = $this->create_test_appointment( $clinic_id, $this->doctor_user, $this->patient_user ); $encounter_id = $this->create_test_encounter( $appointment_id ); $prescription_data = array( 'name' => 'Paracetamol 500mg', 'frequency' => 'Every 8 hours', 'duration' => '7 days', 'instruction' => 'Take with water after meals. Do not exceed recommended dose.', 'dosage' => '1 tablet', 'quantity' => '21 tablets', ); // ACT: Make POST request as doctor $response = $this->make_request( "/wp-json/kivicare/v1/encounters/{$encounter_id}/prescriptions", 'POST', $prescription_data, $this->doctor_user ); // ASSERT: Response contract $this->assertRestResponse( $response, 201 ); $data = $response->get_data(); $this->assertPrescriptionStructure( $data ); $this->assertEquals( $prescription_data['name'], $data['name'] ); $this->assertEquals( $prescription_data['frequency'], $data['frequency'] ); $this->assertEquals( $encounter_id, $data['encounter_id'] ); $this->assertIsInt( $data['id'] ); $this->assertGreaterThan( 0, $data['id'] ); } /** * Test POST /wp-json/kivicare/v1/encounters/{id}/prescriptions with invalid data. * * @test */ public function test_create_prescription_invalid_data() { // This test will fail initially as the endpoint doesn't exist yet $this->markTestIncomplete( 'Prescriptions POST validation not implemented yet - TDD RED phase' ); // ARRANGE: Invalid prescription data $clinic_id = $this->create_test_clinic(); $appointment_id = $this->create_test_appointment( $clinic_id, $this->doctor_user, $this->patient_user ); $encounter_id = $this->create_test_encounter( $appointment_id ); $invalid_data = array( 'name' => '', // Empty name should fail 'frequency' => '', // Empty frequency should fail 'duration' => 'invalid duration format', ); // ACT: Make POST request with invalid data $response = $this->make_request( "/wp-json/kivicare/v1/encounters/{$encounter_id}/prescriptions", 'POST', $invalid_data, $this->doctor_user ); // ASSERT: Validation error contract $this->assertRestResponse( $response, 400 ); $data = $response->get_data(); $this->assertArrayHasKey( 'code', $data ); $this->assertEquals( 'rest_invalid_param', $data['code'] ); $this->assertArrayHasKey( 'data', $data ); $this->assertArrayHasKey( 'params', $data['data'] ); } /** * Test GET /wp-json/kivicare/v1/prescriptions/{id} endpoint contract. * * @test */ public function test_get_prescription_by_id_contract() { // This test will fail initially as the endpoint doesn't exist yet $this->markTestIncomplete( 'Prescription by ID endpoint not implemented yet - TDD RED phase' ); // ARRANGE: Existing prescription $clinic_id = $this->create_test_clinic(); $appointment_id = $this->create_test_appointment( $clinic_id, $this->doctor_user, $this->patient_user ); $encounter_id = $this->create_test_encounter( $appointment_id ); $prescription_id = $this->create_test_prescription( $encounter_id ); // ACT: Make GET request for specific prescription $response = $this->make_request( "/wp-json/kivicare/v1/prescriptions/{$prescription_id}", 'GET', array(), $this->doctor_user ); // ASSERT: Response contract $this->assertRestResponse( $response, 200 ); $data = $response->get_data(); $this->assertPrescriptionStructure( $data ); $this->assertEquals( $prescription_id, $data['id'] ); } /** * Test PUT /wp-json/kivicare/v1/prescriptions/{id} endpoint contract. * * @test */ public function test_update_prescription_contract() { // This test will fail initially as the endpoint doesn't exist yet $this->markTestIncomplete( 'Prescription PUT endpoint not implemented yet - TDD RED phase' ); // ARRANGE: Existing prescription and update data $clinic_id = $this->create_test_clinic(); $appointment_id = $this->create_test_appointment( $clinic_id, $this->doctor_user, $this->patient_user ); $encounter_id = $this->create_test_encounter( $appointment_id ); $prescription_id = $this->create_test_prescription( $encounter_id ); $update_data = array( 'frequency' => 'Every 6 hours', 'duration' => '10 days', 'instruction' => 'Updated instructions: Take with food to avoid stomach irritation.', ); // ACT: Make PUT request to update prescription $response = $this->make_request( "/wp-json/kivicare/v1/prescriptions/{$prescription_id}", 'PUT', $update_data, $this->doctor_user ); // ASSERT: Response contract $this->assertRestResponse( $response, 200 ); $data = $response->get_data(); $this->assertPrescriptionStructure( $data ); $this->assertEquals( $update_data['frequency'], $data['frequency'] ); $this->assertEquals( $update_data['duration'], $data['duration'] ); } /** * Test DELETE /wp-json/kivicare/v1/prescriptions/{id} endpoint contract. * * @test */ public function test_delete_prescription_contract() { // This test will fail initially as the endpoint doesn't exist yet $this->markTestIncomplete( 'Prescription DELETE endpoint not implemented yet - TDD RED phase' ); // ARRANGE: Existing prescription $clinic_id = $this->create_test_clinic(); $appointment_id = $this->create_test_appointment( $clinic_id, $this->doctor_user, $this->patient_user ); $encounter_id = $this->create_test_encounter( $appointment_id ); $prescription_id = $this->create_test_prescription( $encounter_id ); // ACT: Make DELETE request $response = $this->make_request( "/wp-json/kivicare/v1/prescriptions/{$prescription_id}", 'DELETE', array(), $this->doctor_user ); // ASSERT: Response contract $this->assertRestResponse( $response, 200 ); $data = $response->get_data(); $this->assertArrayHasKey( 'deleted', $data ); $this->assertTrue( $data['deleted'] ); $this->assertEquals( $prescription_id, $data['id'] ); } /** * Test prescription bulk operations contract. * * @test */ public function test_bulk_prescription_operations_contract() { // This test will fail initially as bulk operations aren't implemented $this->markTestIncomplete( 'Bulk prescription operations not implemented yet - TDD RED phase' ); // ARRANGE: Multiple prescriptions for an encounter $clinic_id = $this->create_test_clinic(); $appointment_id = $this->create_test_appointment( $clinic_id, $this->doctor_user, $this->patient_user ); $encounter_id = $this->create_test_encounter( $appointment_id ); $bulk_prescriptions = array( array( 'name' => 'Paracetamol 500mg', 'frequency' => 'Every 8 hours', 'duration' => '7 days', 'instruction' => 'Take with water after meals', ), array( 'name' => 'Ibuprofen 400mg', 'frequency' => 'Every 12 hours', 'duration' => '5 days', 'instruction' => 'Take with food to prevent stomach upset', ), ); // ACT: Make bulk POST request $response = $this->make_request( "/wp-json/kivicare/v1/encounters/{$encounter_id}/prescriptions/bulk", 'POST', array( 'prescriptions' => $bulk_prescriptions ), $this->doctor_user ); // ASSERT: Bulk response contract $this->assertRestResponse( $response, 201 ); $data = $response->get_data(); $this->assertIsArray( $data ); $this->assertArrayHasKey( 'created', $data ); $this->assertCount( 2, $data['created'] ); foreach ( $data['created'] as $prescription ) { $this->assertPrescriptionStructure( $prescription ); } } /** * Test prescription permissions by role. * * @test */ public function test_prescription_permissions_contract() { // This test will fail initially as permissions aren't implemented $this->markTestIncomplete( 'Prescription permissions not implemented yet - TDD RED phase' ); // ARRANGE: Prescription created by doctor $clinic_id = $this->create_test_clinic(); $appointment_id = $this->create_test_appointment( $clinic_id, $this->doctor_user, $this->patient_user ); $encounter_id = $this->create_test_encounter( $appointment_id ); $prescription_id = $this->create_test_prescription( $encounter_id ); // ACT & ASSERT: Only doctors should be able to create prescriptions $prescription_data = array( 'name' => 'Test Medicine', 'frequency' => 'Daily', 'duration' => '5 days', ); $response = $this->make_request( "/wp-json/kivicare/v1/encounters/{$encounter_id}/prescriptions", 'POST', $prescription_data, $this->patient_user ); $this->assertRestResponse( $response, 403 ); $response = $this->make_request( "/wp-json/kivicare/v1/encounters/{$encounter_id}/prescriptions", 'POST', $prescription_data, $this->receptionist_user ); $this->assertRestResponse( $response, 403 ); // ACT & ASSERT: Patients should be able to view their prescriptions (read-only) $response = $this->make_request( "/wp-json/kivicare/v1/prescriptions/{$prescription_id}", 'GET', array(), $this->patient_user ); $this->assertRestResponse( $response, 200 ); // ACT & ASSERT: Patients should not be able to modify prescriptions $response = $this->make_request( "/wp-json/kivicare/v1/prescriptions/{$prescription_id}", 'PUT', array( 'frequency' => 'Hacked' ), $this->patient_user ); $this->assertRestResponse( $response, 403 ); } /** * Test prescription drug interaction warnings. * * @test */ public function test_prescription_drug_interactions_contract() { // This test will fail initially as drug interaction checking isn't implemented $this->markTestIncomplete( 'Drug interaction checking not implemented yet - TDD RED phase' ); // ARRANGE: Patient with existing prescription $clinic_id = $this->create_test_clinic(); $appointment_id = $this->create_test_appointment( $clinic_id, $this->doctor_user, $this->patient_user ); $encounter_id = $this->create_test_encounter( $appointment_id ); // Create first prescription $first_prescription = array( 'name' => 'Warfarin 5mg', 'frequency' => 'Daily', 'duration' => '30 days', ); $this->make_request( "/wp-json/kivicare/v1/encounters/{$encounter_id}/prescriptions", 'POST', $first_prescription, $this->doctor_user ); // ACT: Try to add potentially interacting drug $interacting_prescription = array( 'name' => 'Aspirin 100mg', 'frequency' => 'Daily', 'duration' => '7 days', ); $response = $this->make_request( "/wp-json/kivicare/v1/encounters/{$encounter_id}/prescriptions", 'POST', $interacting_prescription, $this->doctor_user ); // ASSERT: Should return warning but allow prescription $this->assertRestResponse( $response, 201 ); $data = $response->get_data(); $this->assertArrayHasKey( 'warnings', $data ); $this->assertArrayHasKey( 'drug_interactions', $data['warnings'] ); } /** * Helper method to create test encounter. * * @param int $appointment_id Appointment ID. * @return int Encounter ID. */ private function create_test_encounter( $appointment_id ) { global $wpdb; $encounter_data = array( 'encounter_date' => gmdate( 'Y-m-d' ), 'clinic_id' => get_option( 'kivicare_api_test_clinic_id', 1 ), 'doctor_id' => $this->doctor_user, 'patient_id' => $this->patient_user, 'appointment_id' => $appointment_id, 'description' => 'Test medical encounter', 'status' => 1, 'added_by' => $this->doctor_user, 'created_at' => current_time( 'mysql' ), ); $wpdb->insert( $wpdb->prefix . 'kc_patient_encounters', $encounter_data ); return $wpdb->insert_id; } /** * Helper method to create test prescription. * * @param int $encounter_id Encounter ID. * @return int Prescription ID. */ private function create_test_prescription( $encounter_id ) { global $wpdb; $prescription_data = array( 'encounter_id' => $encounter_id, 'patient_id' => $this->patient_user, 'name' => 'Test Medicine 100mg', 'frequency' => 'Every 8 hours', 'duration' => '7 days', 'instruction' => 'Take with water', 'added_by' => $this->doctor_user, 'created_at' => current_time( 'mysql' ), ); $wpdb->insert( $wpdb->prefix . 'kc_prescription', $prescription_data ); return $wpdb->insert_id; } /** * Helper method to assert prescription data structure. * * @param array $prescription Prescription data to validate. */ private function assertPrescriptionStructure( $prescription ) { $this->assertIsArray( $prescription ); $expected_fields = array( 'id', 'encounter_id', 'patient_id', 'name', 'frequency', 'duration', 'instruction', 'added_by', 'created_at' ); foreach ( $expected_fields as $field ) { $this->assertArrayHasKey( $field, $prescription ); } // Data type validations $this->assertIsInt( $prescription['id'] ); $this->assertIsInt( $prescription['encounter_id'] ); $this->assertIsInt( $prescription['patient_id'] ); $this->assertIsString( $prescription['name'] ); $this->assertIsString( $prescription['frequency'] ); $this->assertIsString( $prescription['duration'] ); // Optional fields that might be present if ( isset( $prescription['encounter'] ) ) { $this->assertIsArray( $prescription['encounter'] ); } if ( isset( $prescription['patient'] ) ) { $this->assertIsArray( $prescription['patient'] ); $this->assertArrayHasKey( 'display_name', $prescription['patient'] ); } } }