/** * Returns a specific survey as Survey_entity * @param int $sid * * @return mixed * Returns survey_entity or false if it doesn't exist. */ public function get($sid) { $result = $this->mongo_db->where('sid', (int) $sid)->get(self::COLLECTION); if (!empty($result)) { return Survey_entity::build($result[0]); } else { return FALSE; } }
public function test_api_survey_with_status_restrictions() { // Here we are testing all the API but only for status restrictions. // Every other test case should be tested elsewhere. // Cleanup self::$CI->mongo_db->dropCollection('aw_datacollection_test', 'surveys'); self::$CI->mongo_db->dropCollection('aw_datacollection_test', 'call_tasks'); $this->_reset_status_restrictions(); // Shorter statuses. $draft = Survey_entity::STATUS_DRAFT; $open = Survey_entity::STATUS_OPEN; $closed = Survey_entity::STATUS_CLOSED; $canceled = Survey_entity::STATUS_CANCELED; // Login user $this->_change_user(9903); ///////////////////////////////////////////////////////////////// // Set actions to be allowed only in Draft status. $mock_config = self::$status_resctriction_config; $mock_config['enketo collect data'] = array(Survey_entity::STATUS_DRAFT); $mock_config['enketo testrun'] = array(Survey_entity::STATUS_DRAFT); $this->_set_status_restrictions($mock_config); // Logged user is 9903 // User is agent. // Create survey. // Status open. // Valid xml file. // User is assigned to survey. $survey = Survey_entity::build(array('sid' => 1, 'status' => Survey_entity::STATUS_OPEN, 'files' => array('xml' => 'valid_survey.xml'), 'agents' => array(9903))); self::$CI->survey_model->save($survey); // Create call task self::$CI->mongo_db->insert('call_tasks', array('ctid' => 1001, 'number' => "1100500000000", 'created' => Mongo_db::date(), 'updated' => Mongo_db::date(), 'assigned' => Mongo_db::date(), 'author' => 1, 'assignee_uid' => 9903, 'survey_sid' => 1, 'activity' => array())); self::$CI->api_survey_xslt_transform(1); $result = json_decode(self::$CI->output->get_output(), TRUE); $this->assertEquals(array('code' => 403, 'message' => 'Not allowed.'), $result['status']); $this->assertArrayHasKey('xml_form', $result); self::$CI->api_survey_request_respondents(1); $result = json_decode(self::$CI->output->get_output(), TRUE); $this->assertEquals(array('code' => 403, 'message' => 'Not allowed.'), $result['status']); // User assigned to call task. // Call task is assigned to survey. // User is assigned to survey. // Survey is the one data is being submitted for. $_POST = array('csrf_aw_datacollection' => self::$CI->security->get_csrf_hash(), 'respondent' => array('ctid' => 1001, 'form_data' => '<valid><tag/></valid>')); self::$CI->api_survey_enketo_form_submit(1); $result = json_decode(self::$CI->output->get_output(), TRUE); $this->assertEquals(array('code' => 403, 'message' => 'Not allowed.'), $result['status']); ///////////////////////////////////////////////////////////////// // Test again with correct status restrictions. $mock_config = self::$status_resctriction_config; $mock_config['enketo collect data'] = array(Survey_entity::STATUS_OPEN); $mock_config['enketo testrun'] = array(Survey_entity::STATUS_OPEN); $this->_set_status_restrictions($mock_config); self::$CI->api_survey_xslt_transform(1); $result = json_decode(self::$CI->output->get_output(), TRUE); $this->assertEquals(array('code' => 200, 'message' => 'Ok!'), $result['status']); $this->assertArrayHasKey('xml_form', $result); self::$CI->api_survey_request_respondents(1); $result = json_decode(self::$CI->output->get_output(), TRUE); $this->assertEquals(array('code' => 200, 'message' => 'Ok!'), $result['status']); // User assigned to call task. // Call task is assigned to survey. // User is assigned to survey. // Survey is the one data is being submitted for. $_POST = array('csrf_aw_datacollection' => self::$CI->security->get_csrf_hash(), 'respondent' => array('ctid' => 1001, 'form_data' => '<valid><tag/></valid>')); self::$CI->api_survey_enketo_form_submit(1); $result = json_decode(self::$CI->output->get_output(), TRUE); $this->assertEquals(array('code' => 200, 'message' => 'Ok!'), $result['status']); ///////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////// // To test the manage agents api we need an admin. $this->_change_user(9901); // Logged user 9901. // User is administrator. // Create survey. // Status open. // Valid xml file. $survey = Survey_entity::build(array('sid' => 2, 'status' => Survey_entity::STATUS_OPEN, 'files' => array('xml' => 'valid_survey.xml'), 'agents' => array())); self::$CI->survey_model->save($survey); // Create new agent. // Absolute minimum properties for the test. $user_agent = User_entity::build(array('uid' => 8801, 'status' => User_entity::STATUS_ACTIVE, 'roles' => array(ROLE_CC_AGENT))); self::$CI->user_model->save($user_agent); // Set conditions. $mock_config = self::$status_resctriction_config; $mock_config['manage agents'] = array(Survey_entity::STATUS_DRAFT); $this->_set_status_restrictions($mock_config); // User is an agent. // Action assign $_POST = array('uid' => 8801, 'action' => 'assign', 'csrf_aw_datacollection' => self::$CI->security->get_csrf_hash()); self::$CI->api_survey_manage_agents(1); $result = json_decode(self::$CI->output->get_output(), TRUE); $this->assertEquals(array('code' => 403, 'message' => 'Not allowed.'), $result['status']); ///////////////////////////////////////////////////////////////// // Set conditions. $mock_config = self::$status_resctriction_config; $mock_config['manage agents'] = array(Survey_entity::STATUS_OPEN); $this->_set_status_restrictions($mock_config); // User is an agent. // Action assign $_POST = array('uid' => 8801, 'action' => 'assign', 'csrf_aw_datacollection' => self::$CI->security->get_csrf_hash()); self::$CI->api_survey_manage_agents(1); $result = json_decode(self::$CI->output->get_output(), TRUE); $this->assertEquals(array('code' => 200, 'message' => 'Ok!'), $result['status']); }
/** * Handles form to add and edit survey. * * @param int $action * Action to take on the survey add|edit * * @param Survey_entity $survey. * If editing the survey is passed to the function. */ protected function _survey_form_handle($action = 'add', $survey = NULL) { // Config data for the file upload. $file_upload_config = array('upload_path' => '/tmp/', 'allowed_types' => 'xls|xlsx', 'file_name' => md5(microtime(true))); // Load needed libraries $this->load->library('upload', $file_upload_config); $this->load->helper('pyxform'); // Check for status restrictions when editing a survey. if ($action == 'edit') { if ($survey->status_allows('edit any survey def file')) { // Set form validation rules. $this->form_validation->set_rules('survey_file', 'Definition file', 'callback__cb_survey_file_handle'); } if ($survey->status_allows('edit any survey metadata')) { // Set form validation rules. $this->form_validation->set_rules('survey_title', 'Title', 'required'); $this->form_validation->set_rules('survey_client', 'Client', 'required'); $this->form_validation->set_rules('survey_goal', 'Goal', 'is_natural_no_zero'); $this->form_validation->set_rules('survey_introduction', 'Introductory text', 'xss_clean'); $this->form_validation->set_rules('survey_description', 'Description', 'xss_clean'); } } else { // Set form validation rules. $this->form_validation->set_rules('survey_title', 'Title', 'required'); $this->form_validation->set_rules('survey_client', 'Client', 'required'); $this->form_validation->set_rules('survey_goal', 'Goal', 'is_natural_no_zero'); $this->form_validation->set_rules('survey_introduction', 'Introductory text', 'xss_clean'); $this->form_validation->set_rules('survey_description', 'Description', 'xss_clean'); $this->form_validation->set_rules('survey_file', 'Definition file', 'callback__cb_survey_file_handle'); } $this->form_validation->set_error_delimiters('<small class="error">', '</small>'); // If no data submitted show the form. if ($this->form_validation->run() == FALSE) { $this->load->view('base/html_start'); $this->load->view('components/navigation', array('active_menu' => 'surveys')); $this->load->view('surveys/survey_form', array('survey' => $survey)); $this->load->view('base/html_end'); } else { switch ($action) { case 'add': // Prepare survey data to construct a new survey_entity $survey_data = array(); $survey_data['title'] = $this->input->post('survey_title', TRUE); $survey_data['client'] = $this->input->post('survey_client', TRUE); $survey_data['goal'] = $this->input->post('survey_goal') ? (int) $this->input->post('survey_goal') : NULL; //$survey_data['status'] = (int) $this->input->post('survey_status'); $survey_data['status'] = Survey_entity::STATUS_DRAFT; $survey_data['introduction'] = $this->input->post('survey_introduction', TRUE); $survey_data['description'] = $this->input->post('survey_description', TRUE); // Construct survey. $new_survey = Survey_entity::build($survey_data); // Save survey. // Survey files can only be handled after the survey is saved. if (!$this->survey_model->save($new_survey)) { Status_msg::error('An error occurred when saving the survey. Please try again.'); redirect('surveys'); } // The survey is saved. We can rename the file that was just uploaded // if there's one. $file = $this->input->post('survey_file'); if ($file !== FALSE) { $new_survey->save_xls($file); $result = $new_survey->convert_xls_to_xml(); // If the conversion failed, delete the xls file. if ($result->code == 999) { if (file_exists($new_survey->get_xls_full_path())) { unlink($new_survey->get_xls_full_path()); // Remove also from survey object. $new_survey->files['xls'] = NULL; } } // Save again. // If the save files, delete both files. if (!$this->survey_model->save($new_survey)) { // Attempt to delete the uploaded file. if (file_exists($new_survey->get_xls_full_path())) { unlink($new_survey->get_xls_full_path()); } if (file_exists($new_survey->get_xml_full_path())) { unlink($new_survey->get_xml_full_path()); } Status_msg::error('An error occurred when saving the survey. Please try again.'); redirect('surveys'); } // Set status messages. switch ($result->code) { case 101: Status_msg::warning('Survey file successfully converted but there are some warnings:'); foreach ($result->warnings as $value) { Status_msg::warning($value); } break; case 999: Status_msg::error('Survey file conversion failed:'); Status_msg::error($result->message); break; } } // If it reaches this point the survey was saved. Status_msg::success('Survey successfully created.'); redirect('/survey/' . $new_survey->sid); break; case 'edit': if ($survey->status_allows('edit any survey metadata')) { // Set data from form. $survey->title = $this->input->post('survey_title', TRUE); $survey->client = $this->input->post('survey_client', TRUE); $survey->goal = $this->input->post('survey_goal') ? (int) $this->input->post('survey_goal') : NULL; $survey->introduction = $this->input->post('survey_introduction', TRUE); $survey->description = $this->input->post('survey_description', TRUE); } $file = FALSE; if ($survey->status_allows('edit any survey def file')) { // Handle uploaded file. $file = $this->input->post('survey_file'); } if ($file !== FALSE) { // If the user has uploaded a file we save the survey before // handling it. If the file conversion fails no ghost files // will be present. // Unlink previous files if they exist. if (file_exists($survey->files['xls'])) { unlink($survey->files['xls']); } if (file_exists($survey->files['xml'])) { unlink($survey->files['xml']); } // Nullify $survey->files['xls'] = NULL; $survey->files['xml'] = NULL; // Save if (!$this->survey_model->save($survey)) { Status_msg::error('An error occurred when saving the survey. Please try again.'); redirect('surveys'); } // Now handle the file. $survey->save_xls($file); $result = $survey->convert_xls_to_xml(); // Set status messages. switch ($result->code) { case 101: Status_msg::warning('Survey file successfully converted but there are some warnings:'); foreach ($result->warnings as $value) { Status_msg::warning($value); } break; case 999: Status_msg::error('Survey file conversion failed:'); Status_msg::error($result->message); break; } } if (!$this->survey_model->save($survey)) { Status_msg::error('An error occurred when saving the survey. Please try again.'); redirect('surveys'); } Status_msg::success('Survey successfully updated.'); redirect('/survey/' . $survey->sid); break; } } }