Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F1820370
ClientTest.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Size
14 KB
Subscribers
None
ClientTest.php
View Options
<?php
namespace
Sabre\HTTP
;
class
ClientTest
extends
\PHPUnit_Framework_TestCase
{
protected
$client
;
function
testCreateCurlSettingsArrayGET
()
{
$client
=
new
ClientMock
();
$client
->
addCurlSetting
(
CURLOPT_POSTREDIR
,
0
);
$request
=
new
Request
(
'GET'
,
'http://example.org/'
,
[
'X-Foo'
=>
'bar'
]);
$settings
=
[
CURLOPT_RETURNTRANSFER
=>
true
,
CURLOPT_HEADER
=>
true
,
CURLOPT_POSTREDIR
=>
0
,
CURLOPT_HTTPHEADER
=>
[
'X-Foo: bar'
],
CURLOPT_NOBODY
=>
false
,
CURLOPT_URL
=>
'http://example.org/'
,
CURLOPT_CUSTOMREQUEST
=>
'GET'
,
CURLOPT_POSTFIELDS
=>
null
,
CURLOPT_PUT
=>
false
,
];
// FIXME: CURLOPT_PROTOCOLS and CURLOPT_REDIR_PROTOCOLS are currently unsupported by HHVM
// at least if this unit test fails in the future we know it is :)
if
(
defined
(
'HHVM_VERSION'
)
===
false
)
{
$settings
[
CURLOPT_PROTOCOLS
]
=
CURLPROTO_HTTP
|
CURLPROTO_HTTPS
;
$settings
[
CURLOPT_REDIR_PROTOCOLS
]
=
CURLPROTO_HTTP
|
CURLPROTO_HTTPS
;
}
$this
->
assertEquals
(
$settings
,
$client
->
createCurlSettingsArray
(
$request
));
}
function
testCreateCurlSettingsArrayHEAD
()
{
$client
=
new
ClientMock
();
$request
=
new
Request
(
'HEAD'
,
'http://example.org/'
,
[
'X-Foo'
=>
'bar'
]);
$settings
=
[
CURLOPT_RETURNTRANSFER
=>
true
,
CURLOPT_HEADER
=>
true
,
CURLOPT_NOBODY
=>
true
,
CURLOPT_CUSTOMREQUEST
=>
'HEAD'
,
CURLOPT_HTTPHEADER
=>
[
'X-Foo: bar'
],
CURLOPT_URL
=>
'http://example.org/'
,
CURLOPT_POSTFIELDS
=>
''
,
CURLOPT_PUT
=>
false
,
];
// FIXME: CURLOPT_PROTOCOLS and CURLOPT_REDIR_PROTOCOLS are currently unsupported by HHVM
// at least if this unit test fails in the future we know it is :)
if
(
defined
(
'HHVM_VERSION'
)
===
false
)
{
$settings
[
CURLOPT_PROTOCOLS
]
=
CURLPROTO_HTTP
|
CURLPROTO_HTTPS
;
$settings
[
CURLOPT_REDIR_PROTOCOLS
]
=
CURLPROTO_HTTP
|
CURLPROTO_HTTPS
;
}
$this
->
assertEquals
(
$settings
,
$client
->
createCurlSettingsArray
(
$request
));
}
function
testCreateCurlSettingsArrayGETAfterHEAD
()
{
$client
=
new
ClientMock
();
$request
=
new
Request
(
'HEAD'
,
'http://example.org/'
,
[
'X-Foo'
=>
'bar'
]);
// Parsing the settings for this method, and discarding the result.
// This will cause the client to automatically persist previous
// settings and will help us detect problems.
$client
->
createCurlSettingsArray
(
$request
);
// This is the real request.
$request
=
new
Request
(
'GET'
,
'http://example.org/'
,
[
'X-Foo'
=>
'bar'
]);
$settings
=
[
CURLOPT_CUSTOMREQUEST
=>
'GET'
,
CURLOPT_RETURNTRANSFER
=>
true
,
CURLOPT_HEADER
=>
true
,
CURLOPT_HTTPHEADER
=>
[
'X-Foo: bar'
],
CURLOPT_NOBODY
=>
false
,
CURLOPT_URL
=>
'http://example.org/'
,
CURLOPT_POSTFIELDS
=>
''
,
CURLOPT_PUT
=>
false
,
];
// FIXME: CURLOPT_PROTOCOLS and CURLOPT_REDIR_PROTOCOLS are currently unsupported by HHVM
// at least if this unit test fails in the future we know it is :)
if
(
defined
(
'HHVM_VERSION'
)
===
false
)
{
$settings
[
CURLOPT_PROTOCOLS
]
=
CURLPROTO_HTTP
|
CURLPROTO_HTTPS
;
$settings
[
CURLOPT_REDIR_PROTOCOLS
]
=
CURLPROTO_HTTP
|
CURLPROTO_HTTPS
;
}
$this
->
assertEquals
(
$settings
,
$client
->
createCurlSettingsArray
(
$request
));
}
function
testCreateCurlSettingsArrayPUTStream
()
{
$client
=
new
ClientMock
();
$h
=
fopen
(
'php://memory'
,
'r+'
);
fwrite
(
$h
,
'booh'
);
$request
=
new
Request
(
'PUT'
,
'http://example.org/'
,
[
'X-Foo'
=>
'bar'
],
$h
);
$settings
=
[
CURLOPT_RETURNTRANSFER
=>
true
,
CURLOPT_HEADER
=>
true
,
CURLOPT_PUT
=>
true
,
CURLOPT_INFILE
=>
$h
,
CURLOPT_NOBODY
=>
false
,
CURLOPT_CUSTOMREQUEST
=>
'PUT'
,
CURLOPT_HTTPHEADER
=>
[
'X-Foo: bar'
],
CURLOPT_URL
=>
'http://example.org/'
,
];
// FIXME: CURLOPT_PROTOCOLS and CURLOPT_REDIR_PROTOCOLS are currently unsupported by HHVM
// at least if this unit test fails in the future we know it is :)
if
(
defined
(
'HHVM_VERSION'
)
===
false
)
{
$settings
[
CURLOPT_PROTOCOLS
]
=
CURLPROTO_HTTP
|
CURLPROTO_HTTPS
;
$settings
[
CURLOPT_REDIR_PROTOCOLS
]
=
CURLPROTO_HTTP
|
CURLPROTO_HTTPS
;
}
$this
->
assertEquals
(
$settings
,
$client
->
createCurlSettingsArray
(
$request
));
}
function
testCreateCurlSettingsArrayPUTString
()
{
$client
=
new
ClientMock
();
$request
=
new
Request
(
'PUT'
,
'http://example.org/'
,
[
'X-Foo'
=>
'bar'
],
'boo'
);
$settings
=
[
CURLOPT_RETURNTRANSFER
=>
true
,
CURLOPT_HEADER
=>
true
,
CURLOPT_NOBODY
=>
false
,
CURLOPT_POSTFIELDS
=>
'boo'
,
CURLOPT_CUSTOMREQUEST
=>
'PUT'
,
CURLOPT_HTTPHEADER
=>
[
'X-Foo: bar'
],
CURLOPT_URL
=>
'http://example.org/'
,
];
// FIXME: CURLOPT_PROTOCOLS and CURLOPT_REDIR_PROTOCOLS are currently unsupported by HHVM
// at least if this unit test fails in the future we know it is :)
if
(
defined
(
'HHVM_VERSION'
)
===
false
)
{
$settings
[
CURLOPT_PROTOCOLS
]
=
CURLPROTO_HTTP
|
CURLPROTO_HTTPS
;
$settings
[
CURLOPT_REDIR_PROTOCOLS
]
=
CURLPROTO_HTTP
|
CURLPROTO_HTTPS
;
}
$this
->
assertEquals
(
$settings
,
$client
->
createCurlSettingsArray
(
$request
));
}
function
testSend
()
{
$client
=
new
ClientMock
();
$request
=
new
Request
(
'GET'
,
'http://example.org/'
);
$client
->
on
(
'doRequest'
,
function
(
$request
,
&
$response
)
{
$response
=
new
Response
(
200
);
});
$response
=
$client
->
send
(
$request
);
$this
->
assertEquals
(
200
,
$response
->
getStatus
());
}
function
testSendClientError
()
{
$client
=
new
ClientMock
();
$request
=
new
Request
(
'GET'
,
'http://example.org/'
);
$client
->
on
(
'doRequest'
,
function
(
$request
,
&
$response
)
{
throw
new
ClientException
(
'aaah'
,
1
);
});
$called
=
false
;
$client
->
on
(
'exception'
,
function
()
use
(&
$called
)
{
$called
=
true
;
});
try
{
$client
->
send
(
$request
);
$this
->
fail
(
'send() should have thrown an exception'
);
}
catch
(
ClientException
$e
)
{
}
$this
->
assertTrue
(
$called
);
}
function
testSendHttpError
()
{
$client
=
new
ClientMock
();
$request
=
new
Request
(
'GET'
,
'http://example.org/'
);
$client
->
on
(
'doRequest'
,
function
(
$request
,
&
$response
)
{
$response
=
new
Response
(
404
);
});
$called
=
0
;
$client
->
on
(
'error'
,
function
()
use
(&
$called
)
{
$called
++;
});
$client
->
on
(
'error:404'
,
function
()
use
(&
$called
)
{
$called
++;
});
$client
->
send
(
$request
);
$this
->
assertEquals
(
2
,
$called
);
}
function
testSendRetry
()
{
$client
=
new
ClientMock
();
$request
=
new
Request
(
'GET'
,
'http://example.org/'
);
$called
=
0
;
$client
->
on
(
'doRequest'
,
function
(
$request
,
&
$response
)
use
(&
$called
)
{
$called
++;
if
(
$called
<
3
)
{
$response
=
new
Response
(
404
);
}
else
{
$response
=
new
Response
(
200
);
}
});
$errorCalled
=
0
;
$client
->
on
(
'error'
,
function
(
$request
,
$response
,
&
$retry
,
$retryCount
)
use
(&
$errorCalled
)
{
$errorCalled
++;
$retry
=
true
;
});
$response
=
$client
->
send
(
$request
);
$this
->
assertEquals
(
3
,
$called
);
$this
->
assertEquals
(
2
,
$errorCalled
);
$this
->
assertEquals
(
200
,
$response
->
getStatus
());
}
function
testHttpErrorException
()
{
$client
=
new
ClientMock
();
$client
->
setThrowExceptions
(
true
);
$request
=
new
Request
(
'GET'
,
'http://example.org/'
);
$client
->
on
(
'doRequest'
,
function
(
$request
,
&
$response
)
{
$response
=
new
Response
(
404
);
});
try
{
$client
->
send
(
$request
);
$this
->
fail
(
'An exception should have been thrown'
);
}
catch
(
ClientHttpException
$e
)
{
$this
->
assertEquals
(
404
,
$e
->
getHttpStatus
());
$this
->
assertInstanceOf
(
'Sabre
\H
TTP
\R
esponse'
,
$e
->
getResponse
());
}
}
function
testParseCurlResult
()
{
$client
=
new
ClientMock
();
$client
->
on
(
'curlStuff'
,
function
(&
$return
)
{
$return
=
[
[
'header_size'
=>
33
,
'http_code'
=>
200
,
],
0
,
''
,
];
});
$body
=
"HTTP/1.1 200 OK
\r\n
Header1:Val1
\r\n\r\n
Foo"
;
$result
=
$client
->
parseCurlResult
(
$body
,
'foobar'
);
$this
->
assertEquals
(
Client
::
STATUS_SUCCESS
,
$result
[
'status'
]);
$this
->
assertEquals
(
200
,
$result
[
'http_code'
]);
$this
->
assertEquals
(
200
,
$result
[
'response'
]->
getStatus
());
$this
->
assertEquals
([
'Header1'
=>
[
'Val1'
]],
$result
[
'response'
]->
getHeaders
());
$this
->
assertEquals
(
'Foo'
,
$result
[
'response'
]->
getBodyAsString
());
}
function
testParseCurlError
()
{
$client
=
new
ClientMock
();
$client
->
on
(
'curlStuff'
,
function
(&
$return
)
{
$return
=
[
[],
1
,
'Curl error'
,
];
});
$body
=
"HTTP/1.1 200 OK
\r\n
Header1:Val1
\r\n\r\n
Foo"
;
$result
=
$client
->
parseCurlResult
(
$body
,
'foobar'
);
$this
->
assertEquals
(
Client
::
STATUS_CURLERROR
,
$result
[
'status'
]);
$this
->
assertEquals
(
1
,
$result
[
'curl_errno'
]);
$this
->
assertEquals
(
'Curl error'
,
$result
[
'curl_errmsg'
]);
}
function
testDoRequest
()
{
$client
=
new
ClientMock
();
$request
=
new
Request
(
'GET'
,
'http://example.org/'
);
$client
->
on
(
'curlExec'
,
function
(&
$return
)
{
$return
=
"HTTP/1.1 200 OK
\r\n
Header1:Val1
\r\n\r\n
Foo"
;
});
$client
->
on
(
'curlStuff'
,
function
(&
$return
)
{
$return
=
[
[
'header_size'
=>
33
,
'http_code'
=>
200
,
],
0
,
''
,
];
});
$response
=
$client
->
doRequest
(
$request
);
$this
->
assertEquals
(
200
,
$response
->
getStatus
());
$this
->
assertEquals
([
'Header1'
=>
[
'Val1'
]],
$response
->
getHeaders
());
$this
->
assertEquals
(
'Foo'
,
$response
->
getBodyAsString
());
}
function
testDoRequestCurlError
()
{
$client
=
new
ClientMock
();
$request
=
new
Request
(
'GET'
,
'http://example.org/'
);
$client
->
on
(
'curlExec'
,
function
(&
$return
)
{
$return
=
""
;
});
$client
->
on
(
'curlStuff'
,
function
(&
$return
)
{
$return
=
[
[],
1
,
'Curl error'
,
];
});
try
{
$response
=
$client
->
doRequest
(
$request
);
$this
->
fail
(
'This should have thrown an exception'
);
}
catch
(
ClientException
$e
)
{
$this
->
assertEquals
(
1
,
$e
->
getCode
());
$this
->
assertEquals
(
'Curl error'
,
$e
->
getMessage
());
}
}
}
class
ClientMock
extends
Client
{
protected
$persistedSettings
=
[];
/**
* Making this method public.
*
* We are also going to persist all settings this method generates. While
* the underlying object doesn't behave exactly the same, it helps us
* simulate what curl does internally, and helps us identify problems with
* settings that are set by _some_ methods and not correctly reset by other
* methods after subsequent use.
* forces
*/
function
createCurlSettingsArray
(
RequestInterface
$request
)
{
$settings
=
parent
::
createCurlSettingsArray
(
$request
);
$settings
=
$settings
+
$this
->
persistedSettings
;
$this
->
persistedSettings
=
$settings
;
return
$settings
;
}
/**
* Making this method public.
*/
function
parseCurlResult
(
$response
,
$curlHandle
)
{
return
parent
::
parseCurlResult
(
$response
,
$curlHandle
);
}
/**
* This method is responsible for performing a single request.
*
* @param RequestInterface $request
* @return ResponseInterface
*/
function
doRequest
(
RequestInterface
$request
)
{
$response
=
null
;
$this
->
emit
(
'doRequest'
,
[
$request
,
&
$response
]);
// If nothing modified $response, we're using the default behavior.
if
(
is_null
(
$response
))
{
return
parent
::
doRequest
(
$request
);
}
else
{
return
$response
;
}
}
/**
* Returns a bunch of information about a curl request.
*
* This method exists so it can easily be overridden and mocked.
*
* @param resource $curlHandle
* @return array
*/
protected
function
curlStuff
(
$curlHandle
)
{
$return
=
null
;
$this
->
emit
(
'curlStuff'
,
[&
$return
]);
// If nothing modified $return, we're using the default behavior.
if
(
is_null
(
$return
))
{
return
parent
::
curlStuff
(
$curlHandle
);
}
else
{
return
$return
;
}
}
/**
* Calls curl_exec
*
* This method exists so it can easily be overridden and mocked.
*
* @param resource $curlHandle
* @return string
*/
protected
function
curlExec
(
$curlHandle
)
{
$return
=
null
;
$this
->
emit
(
'curlExec'
,
[&
$return
]);
// If nothing modified $return, we're using the default behavior.
if
(
is_null
(
$return
))
{
return
parent
::
curlExec
(
$curlHandle
);
}
else
{
return
$return
;
}
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Sun, Dec 22, 2:17 AM (6 d, 1 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
915564
Default Alt Text
ClientTest.php (14 KB)
Attached To
rDAVCAL DokuWiki DAVCal PlugIn
Event Timeline
Log In to Comment