View source
<?php
class ServicesWebTestCase extends DrupalWebTestCase {
public function setUp(array $modules = array()) {
$modules[] = 'ctools';
$modules[] = 'services';
$modules[] = 'rest_server';
parent::setUp($modules);
$this->cookieFile = drupal_tempnam(variable_get('file_temporary_path'), 'services_cookiejar');
$this->additionalCurlOptions[CURLOPT_COOKIEFILE] = $this->cookieFile;
}
protected function servicesGet($url, $data = NULL, $headers = array()) {
$options = array(
'query' => $data,
);
$url = url($this
->getAbsoluteUrl($url) . '.php', $options);
$content = $this
->curlExec(array(
CURLOPT_HTTPGET => TRUE,
CURLOPT_URL => $url,
CURLOPT_NOBODY => FALSE,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_HEADER => TRUE,
CURLOPT_HTTPHEADER => $headers,
));
list($info, $header, $status, $code, $body) = $this
->parseHeader($content);
$this
->verbose('GET request to: ' . $url . '<hr />headers: ' . highlight_string('<?php ' . var_export($headers, TRUE), TRUE) . '<hr />Arguments: ' . highlight_string('<?php ' . var_export($data, TRUE), TRUE) . '<hr />Response: ' . highlight_string('<?php ' . var_export($body, TRUE), TRUE) . '<hr />Raw response: ' . $content);
return array(
'header' => $header,
'status' => $status,
'code' => $code,
'body' => $body,
);
}
protected function servicesPostFile($url, $filepath, $headers = array(), $additional_arguments = array()) {
$this
->addCSRFHeader($headers);
if (!is_array($filepath)) {
$filepath = array(
$filepath,
);
}
$url = $this
->getAbsoluteUrl($url) . '.php';
$headers[] = "Content-type: multipart/form-data";
$post = $additional_arguments;
$i = 0;
foreach ($filepath as $path) {
$post['files[file_contents' . $i . ']'] = '@' . variable_get('file_public_path', '') . '/' . file_uri_target($path);
$i++;
}
$content = $this
->curlExec(array(
CURLOPT_URL => $url,
CURLOPT_POST => TRUE,
CURLOPT_POSTFIELDS => $post,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_HEADER => TRUE,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_FOLLOWLOCATION => TRUE,
CURLOPT_VERBOSE => TRUE,
));
list($info, $header, $status, $code, $body) = $this
->parseHeader($content);
$this
->verbose('POST request to: ' . $url . '<hr />File Name(s): ' . highlight_string('<?php . ' . var_export($filepath, TRUE), TRUE) . '<hr />Response: ' . highlight_string('<?php ' . var_export($body, TRUE), TRUE) . '<hr />Curl info: ' . highlight_string('<?php ' . var_export($info, TRUE), TRUE) . '<hr />Raw response: ' . $content);
return array(
'header' => $header,
'status' => $status,
'code' => $code,
'body' => $body,
);
}
protected function servicesPost($url, $data = array(), $headers = array(), $call_type = 'php') {
$this
->addCSRFHeader($headers);
switch ($call_type) {
case 'php':
$url = $this
->getAbsoluteUrl($url) . '.php';
$headers[] = "Content-type: application/x-www-form-urlencoded";
$post = drupal_http_build_query($data, '', '&');
break;
case 'json':
$url = $this
->getAbsoluteUrl($url) . '.json';
$headers[] = "Content-type: application/json";
$post = json_encode($data);
break;
}
$content = $this
->curlExec(array(
CURLOPT_URL => $url,
CURLOPT_POST => TRUE,
CURLOPT_POSTFIELDS => $post,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_HEADER => TRUE,
CURLOPT_RETURNTRANSFER => TRUE,
));
list($info, $header, $status, $code, $body) = $this
->parseHeader($content, $call_type);
$this
->verbose('POST request to: ' . $url . '<hr />Arguments: ' . highlight_string('<?php ' . var_export($data, TRUE), TRUE) . '<hr />Raw POST body: ' . $post . '<hr />Response: ' . highlight_string('<?php ' . var_export($body, TRUE), TRUE) . '<hr />Curl info: ' . highlight_string('<?php ' . var_export($info, TRUE), TRUE) . '<hr />Raw response: ' . $content);
return array(
'header' => $header,
'status' => $status,
'code' => $code,
'body' => $body,
);
}
protected function servicesPut($url, $data = NULL, $headers = array(), $call_type = 'php') {
$this
->addCSRFHeader($headers);
switch ($call_type) {
case 'php':
$url = $this
->getAbsoluteUrl($url) . '.php';
$headers[] = "Content-type: application/x-www-form-urlencoded";
$post = drupal_http_build_query($data, '', '&');
break;
case 'json':
$url = $this
->getAbsoluteUrl($url) . '.json';
$headers[] = "Content-type: application/json";
$post = json_encode($data);
break;
}
$putData = fopen('php://temp', 'rw+');
fwrite($putData, $post);
fseek($putData, 0);
$content = $this
->curlExec(array(
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_PUT => TRUE,
CURLOPT_HEADER => TRUE,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_INFILE => $putData,
CURLOPT_INFILESIZE => drupal_strlen($post),
));
fclose($putData);
list($info, $header, $status, $code, $body) = $this
->parseHeader($content, $call_type);
$this
->verbose('PUT request to: ' . $url . '<hr />Arguments: ' . highlight_string('<?php ' . var_export($data, TRUE), TRUE) . '<hr />Raw POST body: ' . $post . '<hr />Response: ' . highlight_string('<?php ' . var_export($body, TRUE), TRUE) . '<hr />Curl info: ' . highlight_string('<?php ' . var_export($info, TRUE), TRUE) . '<hr />Raw response: ' . $content);
return array(
'header' => $header,
'status' => $status,
'code' => $code,
'body' => $body,
);
}
protected function servicesDelete($url, $data = NULL, $headers = array()) {
$this
->addCSRFHeader($headers);
$options = array(
'query' => $data,
);
$url = url($this
->getAbsoluteUrl($url) . '.php', $options);
$content = $this
->curlExec(array(
CURLOPT_URL => $url,
CURLOPT_CUSTOMREQUEST => "DELETE",
CURLOPT_HEADER => TRUE,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_RETURNTRANSFER => TRUE,
));
list($info, $header, $status, $code, $body) = $this
->parseHeader($content);
$this
->verbose('DELETE request to: ' . $url . '<hr />Arguments: ' . highlight_string('<?php ' . var_export($data, TRUE), TRUE) . '<hr />Response: ' . highlight_string('<?php ' . var_export($body, TRUE), TRUE) . '<hr />Curl info: ' . highlight_string('<?php ' . var_export($info, TRUE), TRUE) . '<hr />Raw response: ' . $content);
return array(
'header' => $header,
'status' => $status,
'code' => $code,
'body' => $body,
);
}
protected function servicesHead($url) {
$url = url($this
->getAbsoluteUrl($url) . '.php');
$content = $this
->curlExec(array(
CURLOPT_URL => $url,
CURLOPT_CUSTOMREQUEST => 'HEAD',
CURLOPT_HEADER => TRUE,
CURLOPT_RETURNTRANSFER => TRUE,
));
list($info, $header, $status, $code, $body) = $this
->parseHeader($content);
$this
->verbose('HEAD request to: ' . $url . '<hr />Curl info: ' . highlight_string('<?php ' . var_export($info, TRUE), TRUE) . '<hr />Raw response: ' . $content);
return array(
'header' => $header,
'status' => $status,
'code' => $code,
'body' => $body,
);
}
function parseHeader($content, $call_type = 'php') {
$info = curl_getinfo($this->curlHandle);
$header = drupal_substr($content, 0, $info['header_size']);
$header = str_replace("HTTP/1.1 100 Continue\r\n\r\n", '', $header);
$status = strtok($header, "\r\n");
$code = $info['http_code'];
$raw_body = drupal_substr($content, $info['header_size'], drupal_strlen($content) - $info['header_size']);
switch ($call_type) {
case 'php':
$body = unserialize($raw_body);
break;
case 'json':
$body = json_decode($raw_body);
break;
}
return array(
$info,
$header,
$status,
$code,
$body,
);
}
function addCSRFHeader(&$headers) {
$csrf_token = $this
->drupalGet('services/session/token');
$headers[] = 'X-CSRF-Token: ' . $csrf_token;
}
public function populateEndpointFAPI() {
return array(
'name' => strtolower($this
->randomName(10)),
'path' => $this
->randomName(10),
'server' => 'rest_server',
);
}
public function saveNewEndpoint() {
$edit = $this
->populateEndpointFAPI();
$endpoint = new stdClass();
$endpoint->disabled = FALSE;
$endpoint->api_version = 3;
$endpoint->name = $edit['name'];
$endpoint->server = $edit['server'];
$endpoint->path = $edit['path'];
$endpoint->authentication = array(
'services' => 'services',
);
$endpoint->server_settings = array(
'formatters' => array(
'json' => TRUE,
'bencode' => TRUE,
'rss' => TRUE,
'plist' => TRUE,
'xmlplist' => TRUE,
'php' => TRUE,
'yaml' => TRUE,
'jsonp' => FALSE,
'xml' => FALSE,
),
'parsers' => array(
'application/x-yaml' => TRUE,
'application/json' => TRUE,
'application/vnd.php.serialized' => TRUE,
'application/plist' => TRUE,
'application/plist+xml' => TRUE,
'application/x-www-form-urlencoded' => TRUE,
'multipart/form-data' => TRUE,
),
);
$endpoint->resources = array(
'comment' => array(
'operations' => array(
'create' => array(
'enabled' => 1,
),
'retrieve' => array(
'enabled' => 1,
),
'update' => array(
'enabled' => 1,
),
'delete' => array(
'enabled' => 1,
),
'index' => array(
'enabled' => 1,
),
),
'actions' => array(
'countAll' => array(
'enabled' => 1,
),
'countNew' => array(
'enabled' => 1,
),
),
),
'file' => array(
'operations' => array(
'create' => array(
'enabled' => 1,
),
'retrieve' => array(
'enabled' => 1,
),
'delete' => array(
'enabled' => 1,
),
'index' => array(
'enabled' => 1,
),
),
'actions' => array(
'create_raw' => array(
'enabled' => 1,
),
),
),
'node' => array(
'operations' => array(
'retrieve' => array(
'enabled' => 1,
),
'create' => array(
'enabled' => 1,
),
'update' => array(
'enabled' => 1,
),
'delete' => array(
'enabled' => 1,
),
'index' => array(
'enabled' => 1,
),
),
'relationships' => array(
'files' => array(
'enabled' => 1,
),
'comments' => array(
'enabled' => 1,
),
),
'targeted_actions' => array(
'attach_file' => array(
'enabled' => 1,
),
),
),
'system' => array(
'actions' => array(
'connect' => array(
'enabled' => 1,
),
'get_variable' => array(
'enabled' => 1,
),
'set_variable' => array(
'enabled' => 1,
),
'del_variable' => array(
'enabled' => 1,
),
),
),
'taxonomy_term' => array(
'operations' => array(
'retrieve' => array(
'enabled' => 1,
),
'create' => array(
'enabled' => 1,
),
'update' => array(
'enabled' => 1,
),
'delete' => array(
'enabled' => 1,
),
'index' => array(
'enabled' => 1,
),
),
'actions' => array(
'selectNodes' => array(
'enabled' => 1,
),
),
),
'taxonomy_vocabulary' => array(
'operations' => array(
'retrieve' => array(
'enabled' => 1,
),
'create' => array(
'enabled' => 1,
),
'update' => array(
'enabled' => 1,
),
'delete' => array(
'enabled' => 1,
),
'index' => array(
'enabled' => 1,
),
),
'actions' => array(
'getTree' => array(
'enabled' => 1,
),
),
),
'user' => array(
'operations' => array(
'retrieve' => array(
'enabled' => 1,
),
'create' => array(
'enabled' => 1,
),
'update' => array(
'enabled' => 1,
),
'delete' => array(
'enabled' => 1,
),
'index' => array(
'enabled' => 1,
),
),
'actions' => array(
'login' => array(
'enabled' => 1,
),
'logout' => array(
'enabled' => '1',
'settings' => array(
'services' => array(
'resource_api_version' => '1.1',
),
),
),
'register' => array(
'enabled' => 1,
),
'request_new_password' => array(
'enabled' => 1,
),
),
'targeted_actions' => array(
'cancel' => array(
'enabled' => 1,
),
'password_reset' => array(
'enabled' => 1,
),
'resend_welcome_email' => array(
'enabled' => 1,
),
),
),
);
$endpoint->debug = 1;
$endpoint->export_type = FALSE;
services_endpoint_save($endpoint);
$endpoint = services_endpoint_load($endpoint->name);
$this
->assertTrue($endpoint->name == $edit['name'], 'Endpoint successfully created');
return $endpoint;
}
public function saveNewVersionEndpoint($version = '1.0') {
$edit = $this
->populateEndpointFAPI();
$endpoint = new stdClass();
$endpoint->disabled = FALSE;
$endpoint->api_version = 3;
$endpoint->name = $edit['name'];
$endpoint->server = $edit['server'];
$endpoint->path = $edit['path'];
$endpoint->authentication = array(
'services' => array(),
);
$endpoint->server_settings = array(
'formatters' => array(
'bencode' => TRUE,
'json' => TRUE,
'php' => TRUE,
'plist' => TRUE,
'rss' => TRUE,
'xml' => TRUE,
'xmlplist' => TRUE,
'jsonp' => FALSE,
),
'parsers' => array(
'application/json' => TRUE,
'application/plist' => TRUE,
'application/plist+xml' => TRUE,
'application/vnd.php.serialized' => TRUE,
'multipart/form-data' => TRUE,
'application/x-www-form-urlencoded' => TRUE,
),
);
$endpoint->resources = array(
'comment' => array(
'operations' => array(
'create' => array(
'enabled' => '1',
),
'retrieve' => array(
'enabled' => '1',
),
'update' => array(
'enabled' => '1',
),
'delete' => array(
'enabled' => '1',
),
'index' => array(
'enabled' => '1',
),
),
'actions' => array(
'countAll' => array(
'enabled' => '1',
),
'countNew' => array(
'enabled' => '1',
),
),
),
'file' => array(
'operations' => array(
'create' => array(
'enabled' => '1',
),
'retrieve' => array(
'enabled' => '1',
),
'delete' => array(
'enabled' => '1',
),
'index' => array(
'enabled' => '1',
),
),
'actions' => array(
'create_raw' => array(
'enabled' => '1',
),
),
),
'node' => array(
'operations' => array(
'retrieve' => array(
'enabled' => '1',
),
'create' => array(
'enabled' => '1',
),
'update' => array(
'enabled' => '1',
),
'delete' => array(
'enabled' => '1',
),
'index' => array(
'enabled' => '1',
),
),
'relationships' => array(
'files' => array(
'enabled' => '1',
),
'comments' => array(
'enabled' => '1',
),
),
),
'system' => array(
'actions' => array(
'connect' => array(
'enabled' => '1',
),
'get_variable' => array(
'enabled' => '1',
),
'set_variable' => array(
'enabled' => '1',
),
'del_variable' => array(
'enabled' => '1',
),
),
),
'taxonomy_term' => array(
'operations' => array(
'retrieve' => array(
'enabled' => '1',
),
'create' => array(
'enabled' => '1',
),
'update' => array(
'enabled' => '1',
),
'delete' => array(
'enabled' => '1',
),
'index' => array(
'enabled' => '1',
),
),
'actions' => array(
'selectNodes' => array(
'enabled' => '1',
),
),
),
'taxonomy_vocabulary' => array(
'operations' => array(
'retrieve' => array(
'enabled' => '1',
),
'create' => array(
'enabled' => '1',
),
'update' => array(
'enabled' => '1',
),
'delete' => array(
'enabled' => '1',
),
'index' => array(
'enabled' => '1',
),
),
'actions' => array(
'getTree' => array(
'enabled' => '1',
),
),
),
'user' => array(
'operations' => array(
'retrieve' => array(
'enabled' => '1',
),
'create' => array(
'enabled' => '1',
),
'update' => array(
'enabled' => '1',
),
'delete' => array(
'enabled' => '1',
),
'index' => array(
'enabled' => '1',
),
),
'actions' => array(
'login' => array(
'enabled' => '1',
'settings' => array(
'services' => array(
'resource_api_version' => $version,
),
),
),
'logout' => array(
'enabled' => '1',
),
'register' => array(
'enabled' => '1',
),
),
'targeted_actions' => array(
'cancel' => array(
'enabled' => 1,
),
'password_reset' => array(
'enabled' => 1,
),
'resend_welcome_email' => array(
'enabled' => 1,
),
),
),
'services_test' => array(
'operations' => array(
'retrieve' => array(
'enabled' => '1',
'settings' => array(
'services' => array(
'resource_api_version' => $version,
),
),
),
),
),
'views' => array(
'operations' => array(
'retrieve' => array(
'enabled' => '1',
),
),
),
);
$endpoint->debug = 0;
$endpoint->export_type = FALSE;
services_endpoint_save($endpoint);
$endpoint = services_endpoint_load($endpoint->name);
$this
->assertTrue($endpoint->name == $edit['name'], 'Endpoint successfully created');
return $endpoint;
}
protected function curlExec($curl_options, $redirect = FALSE) {
$this
->curlClose();
$this
->curlInitialize();
if (!empty($curl_options[CURLOPT_URL])) {
if (isset($_COOKIE['XDEBUG_SESSION'])) {
$options = drupal_parse_url($curl_options[CURLOPT_URL]);
$options += array(
'query' => array(),
);
$options['query'] += array(
'XDEBUG_SESSION_START' => $_COOKIE['XDEBUG_SESSION'],
);
$curl_options[CURLOPT_URL] = url($options['path'], $options);
}
if (strpos($curl_options[CURLOPT_URL], '#')) {
$original_url = $curl_options[CURLOPT_URL];
$curl_options[CURLOPT_URL] = strtok($curl_options[CURLOPT_URL], '#');
}
}
$url = empty($curl_options[CURLOPT_URL]) ? curl_getinfo($this->curlHandle, CURLINFO_EFFECTIVE_URL) : $curl_options[CURLOPT_URL];
if (!empty($curl_options[CURLOPT_POST])) {
$curl_options[CURLOPT_HTTPHEADER][] = 'Expect:';
}
curl_setopt_array($this->curlHandle, $this->additionalCurlOptions + $curl_options);
if (!$redirect) {
$this->session_id = NULL;
$this->headers = array();
$this->redirect_count = 0;
}
$content = curl_exec($this->curlHandle);
$status = curl_getinfo($this->curlHandle, CURLINFO_HTTP_CODE);
if (in_array($status, array(
300,
301,
302,
303,
305,
307,
)) && $this->redirect_count < variable_get('simpletest_maximum_redirects', 5)) {
if ($this
->drupalGetHeader('location')) {
$this->redirect_count++;
$curl_options = array();
$curl_options[CURLOPT_URL] = $this
->drupalGetHeader('location');
$curl_options[CURLOPT_HTTPGET] = TRUE;
return $this
->curlExec($curl_options, TRUE);
}
}
$this
->drupalSetContent($content, isset($original_url) ? $original_url : curl_getinfo($this->curlHandle, CURLINFO_EFFECTIVE_URL));
$method = '';
if (!empty($curl_options[CURLOPT_NOBODY])) {
$method = 'HEAD';
}
if (empty($method) && !empty($curl_options[CURLOPT_PUT])) {
$method = 'PUT';
}
if (empty($method) && !empty($curl_options[CURLOPT_CUSTOMREQUEST])) {
$method = $curl_options[CURLOPT_CUSTOMREQUEST];
}
if (empty($method)) {
$method = empty($curl_options[CURLOPT_POSTFIELDS]) ? 'GET' : 'POST';
}
$message_vars = array(
'!method' => $method,
'@url' => isset($original_url) ? $original_url : $url,
'@status' => $status,
'!length' => format_size(drupal_strlen($this
->drupalGetContent())),
);
$message = format_string('!method @url returned @status (!length).', $message_vars);
$this
->assertTrue($this
->drupalGetContent() !== FALSE, $message, 'Browser');
return $this
->drupalGetContent();
}
public function getCommentValues($nid) {
return array(
'subject' => $this
->randomString(),
'comment_body' => array(
LANGUAGE_NONE => array(
array(
'value' => $this
->randomString(),
'format' => filter_default_format(),
),
),
),
'name' => $this->privileged_user->name,
'language' => LANGUAGE_NONE,
'nid' => $nid,
'uid' => $this->privileged_user->uid,
'cid' => NULL,
'pid' => 0,
);
}
}