ServicesWebTestCase.php in Services 6.3
Services base testing class.
File
tests/functional/ServicesWebTestCase.phpView source
<?php
/**
* @file
* Services base testing class.
*/
class ServicesWebTestCase extends DrupalWebTestCase {
protected function servicesGet($url, $data = NULL, $headers = array()) {
$options = array(
'query' => $data,
);
$url = url($this
->getAbsoluteUrl($url) . '.php', $options);
$headers = array();
$content = $this
->curlExec(array(
CURLOPT_HTTPGET => TRUE,
CURLOPT_URL => $url,
CURLOPT_NOBODY => FALSE,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_HEADER => TRUE,
CURLOPT_HTTPHEADER => $headers,
));
// Parse response.
list($info, $header, $status, $code, $body) = $this
->parseHeader($content);
$this
->verbose('GET request to: ' . $url . '<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 servicesPost($url, $data = array(), $headers = array(), $call_type = 'php') {
$options = array();
switch ($call_type) {
case 'php':
// Add .php to get serialized response.
$url = $this
->getAbsoluteUrl($url) . '.php';
// Otherwise Services will reject arguments.
$headers = array(
"Content-type: application/x-www-form-urlencoded",
);
// Prepare arguments.
$post = http_build_query($data, '', '&');
break;
case 'json':
// Add .json to get json encoded response.
$url = $this
->getAbsoluteUrl($url) . '.json';
// Set proper headers.
$headers = array(
"Content-type: application/json",
);
// Prepare arguments.
$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,
));
// Parse response.
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 />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()) {
$options = array();
$url = $this
->getAbsoluteUrl($url) . '.php';
$serialize_args = serialize($data);
// Set up headers so arguments will be unserialized.
$headers = array(
"Content-type: application/vnd.php.serialized; charset=iso-8859-1",
);
// Emulate file.
$putData = fopen('php://memory', 'rw+');
fwrite($putData, $serialize_args);
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($serialize_args),
));
fclose($putData);
// Parse response.
list($info, $header, $status, $code, $body) = $this
->parseHeader($content);
$this
->verbose('PUT 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 servicesDelete($url, $data = NULL, $headers = array()) {
$options = array(
'query' => $data,
);
$url = url($this
->getAbsoluteUrl($url) . '.php', $options);
$content = $this
->curlExec(array(
CURLOPT_URL => $url,
CURLOPT_CUSTOMREQUEST => "DELETE",
CURLOPT_HTTPHEADER => $headers,
CURLOPT_RETURNTRANSFER => TRUE,
));
// Parse response.
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,
);
}
/*
------------------------------------
HELPER METHODS
------------------------------------
*/
/**
* Parse header.
*
* @param type $content
* @return type
*/
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,
);
}
/**
* Creates a data array for populating an endpoint creation form.
*
* @return
* An array of fields for fully populating an endpoint creation form.
*/
public function populateEndpointFAPI() {
return array(
'name' => 'machinename',
'title' => $this
->randomName(20),
'path' => $this
->randomName(10),
'server' => 'rest_server',
'services_use_content_permissions' => TRUE,
);
}
public function saveNewEndpoint() {
$edit = $this
->populateEndpointFAPI();
$endpoint = new stdClass();
$endpoint->disabled = FALSE;
/* Edit this to true to make a default endpoint disabled initially */
$endpoint->api_version = 3;
$endpoint->name = $edit['name'];
$endpoint->title = $edit['title'];
$endpoint->server = $edit['server'];
$endpoint->path = $edit['path'];
$endpoint->authentication = array(
'services' => 'services',
);
$endpoint->server_settings = array(
'rest_server' => 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,
),
),
);
$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,
),
),
),
'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,
),
'logout' => array(
'enabled' => 1,
),
'register' => 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'], t('Endpoint successfully created'));
return $endpoint;
}
/**
* Performs a cURL exec with the specified options after calling curlConnect().
*
* @param $curl_options
* Custom cURL options.
* @return
* Content returned from the exec.
*/
protected function curlExec($curl_options) {
$this
->curlInitialize();
$url = empty($curl_options[CURLOPT_URL]) ? curl_getinfo($this->curlHandle, CURLINFO_EFFECTIVE_URL) : $curl_options[CURLOPT_URL];
if (!empty($curl_options[CURLOPT_POST])) {
// This is a fix for the Curl library to prevent Expect: 100-continue
// headers in POST requests, that may cause unexpected HTTP response
// codes from some webservers (like lighttpd that returns a 417 error
// code). It is done by setting an empty "Expect" header field that is
// not overwritten by Curl.
$curl_options[CURLOPT_HTTPHEADER][] = 'Expect:';
}
curl_setopt_array($this->curlHandle, $this->additionalCurlOptions + $curl_options);
// Reset headers and the session ID.
$this->session_id = NULL;
$this->headers = array();
$this
->drupalSetContent(curl_exec($this->curlHandle), curl_getinfo($this->curlHandle, CURLINFO_EFFECTIVE_URL));
// Analyze the method for log message.
$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' => $url,
'@status' => curl_getinfo($this->curlHandle, CURLINFO_HTTP_CODE),
'!length' => format_size(drupal_strlen($this->content)),
);
$message = t('!method @url returned @status (!length).', $message_vars);
$this
->assertTrue($this->content !== FALSE, $message, t('Browser'));
return $this
->drupalGetContent();
}
}
Classes
Name | Description |
---|---|
ServicesWebTestCase | @file Services base testing class. |