SoapServer/Client now handle binary files correctly & large tests/fixtures update

Soap Server and Client were breaking binary files during transfer due to invalid Mime Message Parser. Now is it working fine with no errors, but the message parser is about to be rewritten into a better form.
This commit is contained in:
Petr Bechyně
2017-04-04 18:36:18 +02:00
parent 311f9e6d08
commit 564005da93
42 changed files with 1135 additions and 250 deletions

View File

@ -3,6 +3,8 @@
namespace BeSimple\SoapClient;
use BeSimple\SoapBundle\Soap\SoapAttachment;
use BeSimple\SoapClient\Curl\CurlOptions;
use BeSimple\SoapClient\SoapOptions\SoapClientOptions;
use BeSimple\SoapCommon\ClassMap;
use BeSimple\SoapCommon\SoapOptions\SoapOptions;
use BeSimple\SoapCommon\SoapOptionsBuilder;
@ -182,8 +184,14 @@ class SoapClientTest extends PHPUnit_Framework_TestCase
self::assertContains('start="<part-', $tracingData->getLastRequestHeaders(), 'Headers should link to first MultiPart');
self::assertContains('action="', $tracingData->getLastRequestHeaders(), 'Headers should contain SOAP action');
self::assertEquals(
$this->removeOneTimeData(file_get_contents(self::FIXTURES_DIR.'/soapRequestWithTwoAttachments.request')),
$this->removeOneTimeData($tracingData->getLastRequest()),
$this->removeOneTimeData(
file_get_contents(
self::FIXTURES_DIR.'/Message/Request/GetUKLocationByCounty.request.mimepart.message'
)
),
$this->removeOneTimeData(
$tracingData->getLastRequest()
),
'Requests must match after onetime data were removed'
);
}
@ -216,7 +224,7 @@ class SoapClientTest extends PHPUnit_Framework_TestCase
self::assertNotContains('start="<part-', $tracingData->getLastRequestHeaders(), 'Headers should link to first MultiPart');
self::assertContains('action="', $tracingData->getLastRequestHeaders(), 'Headers should contain SOAP action');
self::assertStringEqualsFile(
self::FIXTURES_DIR.'/soapRequestWithNoAttachments.request',
self::FIXTURES_DIR.'/Message/Request/GetUKLocationByCounty.request.message',
$tracingData->getLastRequest(),
'Requests must match'
);

View File

@ -0,0 +1,75 @@
<?php
namespace BeSimple\SoapCommon\Mime\Boundary;
use PHPUnit_Framework_TestCase;
class MimeBoundaryAnalyserTest extends PHPUnit_Framework_TestCase
{
const EXPECTED_HAS_BOUNDARY = true;
const EXPECTED_HAS_NO_BOUNDARY = false;
const EXPECTED_IS_BOUNDARY = true;
const EXPECTED_IS_NOT_BOUNDARY = false;
/**
* @dataProvider mimeMessageLinesDataProvider
* @param string[] $mimeMessageLines
* @param bool $expectHasBoundary
*/
public function testHasMessageBoundary(array $mimeMessageLines, $expectHasBoundary)
{
$hasMessageBoundary = MimeBoundaryAnalyser::hasMessageBoundary($mimeMessageLines);
self::assertEquals($expectHasBoundary, $hasMessageBoundary);
}
/**
* @dataProvider mimeMessageLineDataProvider
* @param string $mimeMessageLine
* @param bool $expectIsBoundary
*/
public function testIsMessageLineBoundary($mimeMessageLine, $expectIsBoundary)
{
$isMessageBoundary = MimeBoundaryAnalyser::isMessageLineBoundary($mimeMessageLine);
self::assertEquals($expectIsBoundary, $isMessageBoundary);
}
public function mimeMessageLinesDataProvider()
{
return [
[
[
'',
'mesage line -- has no boundary',
'-- this line is a boundary',
'',
'',
'-- this line is also a boundary --',
' -- this is not a boundary'
],
self::EXPECTED_HAS_BOUNDARY
],
[
[
'',
'mesage line -- has no boundary',
'',
'',
' -- this is not a boundary'
],
self::EXPECTED_HAS_NO_BOUNDARY
]
];
}
public function mimeMessageLineDataProvider()
{
return [
['-- this line is boundary', self::EXPECTED_IS_BOUNDARY],
['-- this line is also a boundary --', self::EXPECTED_IS_BOUNDARY],
['mesage line -- is not boundary', self::EXPECTED_IS_NOT_BOUNDARY],
[' -- mesage line -- is not boundary', self::EXPECTED_IS_NOT_BOUNDARY],
];
}
}

View File

@ -0,0 +1,104 @@
<?php
namespace BeSimple\SoapCommon\Mime\Parser;
use BeSimple\SoapCommon\Mime\MultiPart;
use Exception;
use PHPUnit_Framework_TestCase;
class ParsedPartsGetterTest extends PHPUnit_Framework_TestCase
{
const TEST_CASE_SHOULD_FAIL = true;
const TEST_CASE_SHOULD_NOT_FAIL = false;
/**
* @dataProvider provideMimeMessageLines
* @param MultiPart $multiPart
* @param array $mimeMessageLines
* @param bool $hasHttpRequestHeaders
* @param bool $testCaseShouldFail
* @param string|null $failedTestCaseFailMessage
*/
public function testGetPartsFromMimeMessageLines(
MultiPart $multiPart,
array $mimeMessageLines,
$hasHttpRequestHeaders,
$testCaseShouldFail,
$failedTestCaseFailMessage = null
) {
if ($testCaseShouldFail === true) {
$this->setExpectedException(Exception::class, $failedTestCaseFailMessage);
}
$parsedPartsList = ParsedPartsGetter::getPartsFromMimeMessageLines(
$multiPart,
$mimeMessageLines,
$hasHttpRequestHeaders
);
if ($testCaseShouldFail === false) {
self::assertInstanceOf(ParsedPartList::class, $parsedPartsList);
self::assertGreaterThanOrEqual(3, $parsedPartsList->getPartCount());
self::assertTrue($parsedPartsList->hasExactlyOneMainPart());
}
}
public function provideMimeMessageLines()
{
$mimePartWithHeadersForSwaResponse = new MultiPart();
$mimePartWithHeadersForSwaResponse->setHeader('Content-Type', 'boundary', 'Part_13_58e3bc35f3743.58e3bc35f376f');
$mimePartWithHeadersForSwaResponse->setHeader('Content-Type', 'start', '<part-424dbe68-e2da-450f-9a82-cc3e82742503@response.info>');
$mimePartWithWrongHeadersForSwaResponse = new MultiPart();
$mimePartWithWrongHeadersForSwaResponse->setHeader('Content-Type', 'boundary', 'non-existing');
$mimePartWithWrongHeadersForSwaResponse->setHeader('Content-Type', 'start', '<does-not-exist>');
$mimePartWithHeadersForSwaRequest = new MultiPart();
$mimePartWithHeadersForSwaRequest->setHeader('Content-Type', 'boundary', '----=_Part_6_2094841787.1482231370463');
$mimePartWithHeadersForSwaRequest->setHeader('Content-Type', 'start', '<rootpart@soapui.org>');
return [
'ParseSwaResponseWith2FilesAnd1BinaryFile' => [
$mimePartWithHeadersForSwaResponse,
$this->getMessageLinesFromMimeMessage(__DIR__.'/../../../../Fixtures/Message/Response/dummyServiceMethodWithOutgoingLargeSwa.response.mimepart.message'),
ParsedPartsGetter::HAS_HTTP_REQUEST_HEADERS,
self::TEST_CASE_SHOULD_NOT_FAIL
],
'ParseSwaResponseWith2FilesAnd1BinaryFileShouldFailWithNoHeaders' => [
new MultiPart(),
$this->getMessageLinesFromMimeMessage(__DIR__.'/../../../../Fixtures/Message/Response/dummyServiceMethodWithOutgoingLargeSwa.response.mimepart.message'),
ParsedPartsGetter::HAS_NO_HTTP_REQUEST_HEADERS,
self::TEST_CASE_SHOULD_FAIL,
'Unable to get Content-Type boundary'
],
'ParseSwaResponseWith2FilesAnd1BinaryFileShouldFailWithWrongHeaders' => [
$mimePartWithWrongHeadersForSwaResponse,
$this->getMessageLinesFromMimeMessage(__DIR__.'/../../../../Fixtures/Message/Response/dummyServiceMethodWithOutgoingLargeSwa.response.mimepart.message'),
ParsedPartsGetter::HAS_HTTP_REQUEST_HEADERS,
self::TEST_CASE_SHOULD_FAIL,
'cannot parse headers before hitting the first boundary'
],
'ParseSwaRequestWith2Files' => [
$mimePartWithHeadersForSwaRequest,
$this->getMessageLinesFromMimeMessage(__DIR__ . '/../../../../Fixtures/Message/Request/dummyServiceMethodWithAttachments.request.mimepart.message'),
ParsedPartsGetter::HAS_HTTP_REQUEST_HEADERS,
self::TEST_CASE_SHOULD_NOT_FAIL
],
'ParseSwaRequestWith2FilesShouldFailWithNoHeaders' => [
new MultiPart(),
$this->getMessageLinesFromMimeMessage(__DIR__ . '/../../../../Fixtures/Message/Request/dummyServiceMethodWithAttachments.request.mimepart.message'),
ParsedPartsGetter::HAS_NO_HTTP_REQUEST_HEADERS,
self::TEST_CASE_SHOULD_FAIL,
'Unable to get Content-Type boundary'
],
];
}
private function getMessageLinesFromMimeMessage($filePath)
{
if (file_exists($filePath) === false) {
self::fail('Please, update tests data provider - file not found: '.$filePath);
}
return explode("\n", file_get_contents($filePath));
}
}

View File

@ -46,7 +46,7 @@ class SoapServerTest extends PHPUnit_Framework_TestCase
$dummyService->getEndpoint(),
'DummyService.dummyServiceMethod',
'text/xml;charset=UTF-8',
file_get_contents(self::FIXTURES_DIR.DIRECTORY_SEPARATOR.'testHandleRequest.message')
file_get_contents(self::FIXTURES_DIR.'/Message/Request/dummyServiceMethod.message.request')
);
$response = $soapServer->handleRequest($request);
@ -74,7 +74,7 @@ class SoapServerTest extends PHPUnit_Framework_TestCase
$dummyService->getEndpoint(),
'DummyService.dummyServiceMethodWithAttachments',
'text/xml;charset=UTF-8',
file_get_contents(self::FIXTURES_DIR.DIRECTORY_SEPARATOR.'testHandleRequestWithSwa.message')
file_get_contents(self::FIXTURES_DIR.'/Message/Request/dummyServiceMethodWithAttachments.request.message')
);
$response = $soapServer->handleRequest($request);
@ -83,7 +83,7 @@ class SoapServerTest extends PHPUnit_Framework_TestCase
self::assertNotContains("\r\n", $response->getContent(), 'Response cannot contain CRLF line endings');
self::assertContains('dummyServiceMethodWithAttachmentsResponse', $response->getContent());
self::assertSame('DummyService.dummyServiceMethodWithAttachments', $response->getAction());
self::assertFalse($response->hasAttachments(), 'Response should contain attachments');
self::assertFalse($response->hasAttachments(), 'Response should not contain attachments');
}
public function testHandleRequestWithSwaResponse()
@ -102,7 +102,7 @@ class SoapServerTest extends PHPUnit_Framework_TestCase
$dummyService->getEndpoint(),
'DummyService.dummyServiceMethodWithAttachments',
'multipart/related; type="text/xml"; start="<rootpart@soapui.org>"; boundary="----=_Part_6_2094841787.1482231370463"',
file_get_contents(self::FIXTURES_DIR.DIRECTORY_SEPARATOR.'testHandleRequestWithSwa.mimepart.message')
file_get_contents(self::FIXTURES_DIR.'/Message/Request/dummyServiceMethodWithAttachments.request.mimepart.message')
);
$response = $soapServer->handleRequest($request);

View File

@ -0,0 +1,266 @@
<?php
namespace BeSimple;
use BeSimple\SoapBundle\Soap\SoapAttachment;
use BeSimple\SoapClient\SoapClientBuilder;
use BeSimple\SoapClient\SoapClientBuilderTest;
use BeSimple\SoapClient\SoapClientOptionsBuilder;
use BeSimple\SoapClient\SoapFaultWithTracingData;
use BeSimple\SoapCommon\ClassMap;
use BeSimple\SoapCommon\SoapOptions\SoapOptions;
use BeSimple\SoapCommon\SoapOptionsBuilder;
use BeSimple\SoapServer\SoapServerBuilder;
use BeSimple\SoapServer\SoapServerOptionsBuilder;
use Fixtures\DummyService;
use Fixtures\DummyServiceMethodWithIncomingLargeSwaRequest;
use Fixtures\DummyServiceMethodWithOutgoingLargeSwaRequest;
use Fixtures\GenerateTestRequest;
use PHPUnit_Framework_TestCase;
use SoapHeader;
class SoapServerAndSoapClientCommunicationTest extends PHPUnit_Framework_TestCase
{
const CACHE_DIR = __DIR__ . '/../../cache';
const FIXTURES_DIR = __DIR__ . '/../Fixtures';
const TEST_HTTP_URL = 'http://localhost:8000/tests';
const TEST_LOCAL_WSDL_UK = SoapClientBuilderTest::TEST_LOCAL_WSDL_UK;
const LARGE_SWA_FILE = self::FIXTURES_DIR.'/large-test-file.docx';
private $localWebServerProcess;
public function setUp()
{
$this->localWebServerProcess = popen('php -S localhost:8000 > /dev/null 2>&1 &', 'r');
}
public function tearDown()
{
pclose($this->localWebServerProcess);
}
public function testHandleRequestWithLargeSwaResponse()
{
$dummyService = new DummyService();
$classMap = new ClassMap();
foreach ($dummyService->getClassMap() as $type => $className) {
$classMap->add($type, $className);
}
$soapServerBuilder = new SoapServerBuilder();
$soapServerOptions = SoapServerOptionsBuilder::createWithDefaults($dummyService);
$soapOptions = SoapOptionsBuilder::createSwaWithClassMap($dummyService->getWsdlPath(), $classMap);
$soapServer = $soapServerBuilder->build($soapServerOptions, $soapOptions);
$request = $soapServer->createRequest(
$dummyService->getEndpoint(),
'DummyService.dummyServiceMethodWithOutgoingLargeSwa',
'text/xml;charset=UTF-8',
file_get_contents(self::FIXTURES_DIR.'/Message/Request/dummyServiceMethodWithOutgoingLargeSwa.request.message')
);
$response = $soapServer->handleRequest($request);
file_put_contents(self::CACHE_DIR . '/content-type-soap-server-response.xml', $response->getContentType());
file_put_contents(self::CACHE_DIR . '/multipart-message-soap-server-response.xml', $response->getContent());
if ($response->hasAttachments() === true) {
foreach ($response->getAttachments() as $attachment) {
$fileName = preg_replace('/\<|\>/', '', $attachment->getContentId());
file_put_contents(self::CACHE_DIR . DIRECTORY_SEPARATOR . 'attachment-server-response-' . $fileName, $attachment->getContent());
self::assertRegExp('/filename\.(docx|html|txt)/', $fileName);
}
} else {
self::fail('Response should contain attachments');
}
self::assertContains('dummyServiceMethodWithOutgoingLargeSwaResponse', $response->getContent());
self::assertSame('DummyService.dummyServiceMethodWithOutgoingLargeSwa', $response->getAction());
self::assertEquals(
filesize(self::LARGE_SWA_FILE),
filesize(self::CACHE_DIR.'/attachment-server-response-filename.docx'),
'File cannot differ after transport from SoapClient to SoapServer'
);
}
public function testSoapCallSwaWithLargeSwaResponse()
{
$soapClient = $this->getSoapBuilder()->buildWithSoapHeader(
SoapClientOptionsBuilder::createWithEndpointLocation(
self::TEST_HTTP_URL.'/SwaSenderEndpoint.php'
),
SoapOptionsBuilder::createSwaWithClassMap(
self::TEST_HTTP_URL.'/SwaSenderEndpoint.php?wsdl',
new ClassMap([
'GenerateTestRequest' => GenerateTestRequest::class,
]),
SoapOptions::SOAP_CACHE_TYPE_NONE
),
new SoapHeader('http://schema.testcase', 'SoapHeader', [
'user' => 'admin',
])
);
$request = new DummyServiceMethodWithOutgoingLargeSwaRequest();
$request->dummyAttribute = 1;
$soapResponse = $soapClient->soapCall('dummyServiceMethodWithOutgoingLargeSwa', [$request]);
$attachments = $soapResponse->getAttachments();
self::assertContains('</dummyServiceReturn>', $soapResponse->getResponseContent());
self::assertTrue($soapResponse->hasAttachments(), 'Response should contain attachments');
self::assertCount(3, $attachments);
file_put_contents(self::CACHE_DIR . '/multipart-message-soap-client-response.xml', $soapResponse->getContent());
foreach ($soapResponse->getAttachments() as $attachment) {
$fileName = preg_replace('/\<|\>/', '', $attachment->getContentId());
file_put_contents(self::CACHE_DIR . DIRECTORY_SEPARATOR . 'attachment-client-response-' . $fileName, $attachment->getContent());
self::assertRegExp('/filename\.(docx|html|txt)/', $fileName);
}
self::assertEquals(
filesize(self::LARGE_SWA_FILE),
filesize(self::CACHE_DIR.'/attachment-client-response-filename.docx'),
'File cannot differ after transport from SoapClient to SoapServer'
);
}
public function testSoapCallWithLargeSwaRequest()
{
$soapClient = $this->getSoapBuilder()->buildWithSoapHeader(
SoapClientOptionsBuilder::createWithEndpointLocation(
self::TEST_HTTP_URL.'/SwaReceiverEndpoint.php'
),
SoapOptionsBuilder::createSwaWithClassMap(
self::TEST_HTTP_URL.'/SwaReceiverEndpoint.php?wsdl',
new ClassMap([
'DummyServiceMethodWithIncomingLargeSwaRequest' => DummyServiceMethodWithIncomingLargeSwaRequest::class,
]),
SoapOptions::SOAP_CACHE_TYPE_NONE
),
new SoapHeader('http://schema.testcase', 'SoapHeader', [
'user' => 'admin',
])
);
$request = new DummyServiceMethodWithIncomingLargeSwaRequest();
$request->dummyAttribute = 1;
try {
$soapResponse = $soapClient->soapCall(
'dummyServiceMethodWithIncomingLargeSwa',
[$request],
[
new SoapAttachment('filename.txt', 'text/plain', 'plaintext file'),
new SoapAttachment('filename.html', 'text/html', '<html><body>Hello world</body></html>'),
new SoapAttachment(
'filename.docx',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
file_get_contents(self::LARGE_SWA_FILE)
),
]
);
self::assertContains('dummyServiceMethodWithIncomingLargeSwa', $soapResponse->getRequest()->getContent());
self::assertContains('</dummyServiceReturn>', $soapResponse->getResponseContent());
self::assertTrue($soapResponse->getRequest()->hasAttachments(), 'Response MUST contain attachments');
self::assertFalse($soapResponse->hasAttachments(), 'Response MUST NOT contain attachments');
foreach ($soapResponse->getRequest()->getAttachments() as $attachment) {
file_put_contents(self::CACHE_DIR . '/attachment-client-request-'.trim($attachment->getContentId(), '<>'), $attachment->getContent());
}
file_put_contents(self::CACHE_DIR . '/content-type-soap-client-request.xml', $soapResponse->getRequest()->getContentType());
file_put_contents(self::CACHE_DIR.'/multipart-message-soap-client-request.xml', $soapResponse->getRequest()->getContent());
self::assertEquals(
filesize(self::LARGE_SWA_FILE),
filesize(self::CACHE_DIR.'/attachment-client-request-filename.docx'),
'File cannot differ after transport from SoapClient to SoapServer'
);
} catch (SoapFaultWithTracingData $e) {
self::fail(
'Endpoint did not return expected response: '.var_export($e->getSoapResponseTracingData()->getLastResponse(), true)
);
}
}
public function testHandleRequestWithLargeSwaRequest()
{
$previousSoapClientCallContentTypeCacheFile = self::CACHE_DIR.'/content-type-soap-client-request.xml';
$previousSoapClientCallMessageBodyCacheFile = self::CACHE_DIR.'/multipart-message-soap-client-request.xml';
if (file_exists($previousSoapClientCallContentTypeCacheFile) === false || file_exists($previousSoapClientCallMessageBodyCacheFile) === false) {
self::fail('Cannot load data from cache: run testSoapCallWithLargeSwaRequest to get the data.');
}
$previousSoapClientCallContentType = file_get_contents($previousSoapClientCallContentTypeCacheFile);
$previousSoapClientCallMessageBody = file_get_contents($previousSoapClientCallMessageBodyCacheFile);
$dummyService = new DummyService();
$classMap = new ClassMap();
foreach ($dummyService->getClassMap() as $type => $className) {
$classMap->add($type, $className);
}
$soapServerBuilder = new SoapServerBuilder();
$soapServerOptions = SoapServerOptionsBuilder::createWithDefaults($dummyService);
$soapOptions = SoapOptionsBuilder::createSwaWithClassMap($dummyService->getWsdlPath(), $classMap);
$soapServer = $soapServerBuilder->build($soapServerOptions, $soapOptions);
$request = $soapServer->createRequest(
$dummyService->getEndpoint(),
'DummyService.dummyServiceMethodWithIncomingLargeSwa',
$previousSoapClientCallContentType,
$previousSoapClientCallMessageBody
);
$response = $soapServer->handleRequest($request);
self::assertContains('dummyServiceMethodWithIncomingLargeSwaResponse', $response->getContent());
self::assertSame('DummyService.dummyServiceMethodWithIncomingLargeSwa', $response->getAction());
self::assertEquals(
filesize(self::LARGE_SWA_FILE),
filesize(self::CACHE_DIR.'/attachment-server-request-filename.docx'),
'File cannot differ after transport from SoapClient to SoapServer'
);
}
public function testHandleRequestWithLargeSwaRequestAndMixedCrLf()
{
$soapClientCallContentType = file_get_contents(self::FIXTURES_DIR.'/Message/Request/dummyServiceMethodWithIncomingLargeSwaAndMixedCrLf.contenttypeheaders');
$soapClientCallMessageBody = file_get_contents(self::FIXTURES_DIR.'/Message/Request/dummyServiceMethodWithIncomingLargeSwaAndMixedCrLf.request.mimepart.message');
$dummyService = new DummyService();
$classMap = new ClassMap();
foreach ($dummyService->getClassMap() as $type => $className) {
$classMap->add($type, $className);
}
$soapServerBuilder = new SoapServerBuilder();
$soapServerOptions = SoapServerOptionsBuilder::createWithDefaults($dummyService);
$soapOptions = SoapOptionsBuilder::createSwaWithClassMap($dummyService->getWsdlPath(), $classMap);
$soapServer = $soapServerBuilder->build($soapServerOptions, $soapOptions);
$request = $soapServer->createRequest(
$dummyService->getEndpoint(),
'DummyService.dummyServiceMethodWithIncomingLargeSwa',
$soapClientCallContentType,
$soapClientCallMessageBody
);
$response = $soapServer->handleRequest($request);
self::assertContains('dummyServiceMethodWithIncomingLargeSwaResponse', $response->getContent());
self::assertSame('DummyService.dummyServiceMethodWithIncomingLargeSwa', $response->getAction());
self::assertEquals(
filesize(self::LARGE_SWA_FILE),
filesize(self::CACHE_DIR.'/attachment-server-request-oldfilename.docx'),
'File cannot differ after transport from SoapClient to SoapServer'
);
}
private function getSoapBuilder()
{
return new SoapClientBuilder();
}
public function getSoapServerBuilder()
{
return new SoapServerBuilder();
}
}

View File

@ -0,0 +1,16 @@
<?php
namespace Fixtures\Attachment;
trait MessageWithAttachmentsTrait
{
/**
* @var AttachmentCollection $attachmentCollection
*/
public $attachmentCollection;
public function hasAttachments()
{
return $this->attachmentCollection !== null && $this->attachmentCollection->hasAttachments();
}
}

View File

@ -34,6 +34,10 @@ class DummyService implements AttachmentsHandlerInterface
'DummyServiceResponseWithAttachments' => DummyServiceResponseWithAttachments::class,
'DummyServiceRequest' => DummyServiceRequest::class,
'DummyServiceRequestWithAttachments' => DummyServiceRequestWithAttachments::class,
'DummyServiceMethodWithOutgoingLargeSwaRequest' => DummyServiceMethodWithOutgoingLargeSwaRequest::class,
'DummyServiceMethodWithOutgoingLargeSwaResponse' => DummyServiceMethodWithOutgoingLargeSwaResponse::class,
'DummyServiceMethodWithIncomingLargeSwaRequest' => DummyServiceMethodWithIncomingLargeSwaRequest::class,
'DummyServiceMethodWithIncomingLargeSwaResponse' => DummyServiceMethodWithIncomingLargeSwaResponse::class,
];
}
@ -67,6 +71,54 @@ class DummyService implements AttachmentsHandlerInterface
return $dummyServiceHandler->handle($dummyServiceRequest);
}
/**
* @param DummyServiceMethodWithOutgoingLargeSwaRequest $dummyServiceRequest
* @return DummyServiceMethodWithOutgoingLargeSwaResponse
*/
public function dummyServiceMethodWithOutgoingLargeSwa(DummyServiceMethodWithOutgoingLargeSwaRequest $dummyServiceRequest)
{
$dummyServiceHandler = new DummyServiceHandlerWithOutgoingLargeSwa();
$dummyServiceResponseWithAttachments = $dummyServiceHandler->handle($dummyServiceRequest);
if ($dummyServiceResponseWithAttachments->hasAttachments() === true) {
$soapAttachments = [];
foreach ($dummyServiceResponseWithAttachments->attachmentCollection->attachments as $attachment) {
$soapAttachments[] = new SoapAttachment(
$attachment->fileName,
$attachment->contentType,
$attachment->content
);
}
$this->addAttachmentStorage(new RequestHandlerAttachmentsStorage($soapAttachments));
}
return $dummyServiceResponseWithAttachments;
}
/**
* @param DummyServiceMethodWithIncomingLargeSwaRequest $dummyServiceRequest
* @return DummyServiceMethodWithIncomingLargeSwaResponse
*/
public function dummyServiceMethodWithIncomingLargeSwa(DummyServiceMethodWithIncomingLargeSwaRequest $dummyServiceRequest)
{
$dummyServiceHandler = new DummyServiceHandlerWithIncomingLargeSwa();
$attachmentStorageContents = $this->getAttachmentStorage()->getAttachments();
if (count($attachmentStorageContents) > 0) {
$attachments = [];
foreach ($attachmentStorageContents as $soapAttachment) {
$attachments[] = new Attachment(
$soapAttachment->getId(),
$soapAttachment->getType(),
$soapAttachment->getContent()
);
}
$dummyServiceRequest->attachmentCollection = new AttachmentCollection($attachments);
}
return $dummyServiceHandler->handle($dummyServiceRequest);
}
/**
* @param DummyServiceRequestWithAttachments $dummyServiceRequestWithAttachments
* @return DummyServiceResponseWithAttachments

View File

@ -22,6 +22,26 @@
<xsd:element name="status" type="xsd:boolean" minOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="DummyServiceMethodWithOutgoingLargeSwaRequest">
<xsd:sequence>
<xsd:element name="dummyAttribute" type="xsd:int" minOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="DummyServiceMethodWithOutgoingLargeSwaResponse">
<xsd:sequence>
<xsd:element name="status" type="xsd:boolean" minOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="DummyServiceMethodWithIncomingLargeSwaRequest">
<xsd:sequence>
<xsd:element name="dummyAttribute" type="xsd:int" minOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="DummyServiceMethodWithIncomingLargeSwaResponse">
<xsd:sequence>
<xsd:element name="status" type="xsd:boolean" minOccurs="1"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="DummyServiceRequestWithAttachments">
<xsd:sequence>
<xsd:element name="dummyAttribute" type="xsd:int" minOccurs="1"/>
@ -41,12 +61,24 @@
<message name="DummyServiceRequest">
<part name="request" type="tns:DummyServiceRequest"/>
</message>
<message name="DummyServiceMethodWithOutgoingLargeSwaRequest">
<part name="request" type="tns:DummyServiceMethodWithOutgoingLargeSwaRequest"/>
</message>
<message name="DummyServiceMethodWithIncomingLargeSwaRequest">
<part name="request" type="tns:DummyServiceMethodWithIncomingLargeSwaRequest"/>
</message>
<message name="DummyServiceRequestWithAttachments">
<part name="request" type="tns:DummyServiceRequestWithAttachments"/>
</message>
<message name="DummyServiceResponse">
<part name="dummyServiceReturn" type="tns:DummyServiceResponse"/>
</message>
<message name="DummyServiceMethodWithOutgoingLargeSwaResponse">
<part name="dummyServiceReturn" type="tns:DummyServiceMethodWithOutgoingLargeSwaResponse"/>
</message>
<message name="DummyServiceMethodWithIncomingLargeSwaResponse">
<part name="dummyServiceReturn" type="tns:DummyServiceMethodWithIncomingLargeSwaResponse"/>
</message>
<message name="DummyServiceResponseWithAttachments">
<part name="dummyServiceReturn" type="tns:DummyServiceResponseWithAttachments"/>
</message>
@ -55,6 +87,14 @@
<wsdl:input message="tns:DummyServiceRequest"/>
<wsdl:output message="tns:DummyServiceResponse"/>
</wsdl:operation>
<wsdl:operation name="dummyServiceMethodWithOutgoingLargeSwa">
<wsdl:input message="tns:DummyServiceMethodWithOutgoingLargeSwaRequest"/>
<wsdl:output message="tns:DummyServiceMethodWithOutgoingLargeSwaResponse"/>
</wsdl:operation>
<wsdl:operation name="dummyServiceMethodWithIncomingLargeSwa">
<wsdl:input message="tns:DummyServiceMethodWithIncomingLargeSwaRequest"/>
<wsdl:output message="tns:DummyServiceMethodWithIncomingLargeSwaResponse"/>
</wsdl:operation>
<wsdl:operation name="dummyServiceMethodWithAttachments">
<wsdl:input message="tns:DummyServiceRequestWithAttachments"/>
<wsdl:output message="tns:DummyServiceResponseWithAttachments"/>
@ -72,6 +112,26 @@
<soap:body use="literal" namespace="http://schema.testcase"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="dummyServiceMethodWithIncomingLargeSwa">
<soap:operation soapAction="DummyService.dummyServiceMethodWithIncomingLargeSwa" style="rpc"/>
<wsdl:input>
<soap:header use="literal" message="tns:SoapHeader" part="SoapHeader" namespace="http://schema.testcase"/>
<soap:body use="literal" part="request" namespace="http://schema.testcase"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal" namespace="http://schema.testcase"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="dummyServiceMethodWithOutgoingLargeSwa">
<soap:operation soapAction="DummyService.dummyServiceMethodWithOutgoingLargeSwa" style="rpc"/>
<wsdl:input>
<soap:header use="literal" message="tns:SoapHeader" part="SoapHeader" namespace="http://schema.testcase"/>
<soap:body use="literal" part="request" namespace="http://schema.testcase"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal" namespace="http://schema.testcase"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="dummyServiceMethodWithAttachments">
<soap:operation soapAction="DummyService.dummyServiceMethodWithAttachments" style="rpc"/>
<wsdl:input>

View File

@ -0,0 +1,27 @@
<?php
namespace Fixtures;
class DummyServiceHandlerWithIncomingLargeSwa
{
/**
* @param DummyServiceMethodWithIncomingLargeSwaRequest $request
* @return DummyServiceMethodWithIncomingLargeSwaResponse
*/
public function handle(DummyServiceMethodWithIncomingLargeSwaRequest $request)
{
if ($request->hasAttachments() === true) {
foreach ($request->attachmentCollection->attachments as $attachment) {
file_put_contents(
__DIR__.'/../../cache/attachment-server-request-'.$attachment->fileName,
$attachment->content
);
}
}
$response = new DummyServiceMethodWithIncomingLargeSwaResponse();
$response->status = true;
return $response;
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace Fixtures;
use BeSimple\SoapServerAndSoapClientCommunicationTest;
use Fixtures\Attachment\Attachment;
use Fixtures\Attachment\AttachmentCollection;
class DummyServiceHandlerWithOutgoingLargeSwa
{
/**
* @param DummyServiceMethodWithOutgoingLargeSwaRequest $request
* @return DummyServiceMethodWithOutgoingLargeSwaResponse
*/
public function handle(DummyServiceMethodWithOutgoingLargeSwaRequest $request)
{
$response = new DummyServiceMethodWithOutgoingLargeSwaResponse();
$response->status = true;
$response->attachmentCollection = new AttachmentCollection([
new Attachment('filename.txt', 'text/plain', 'plaintext file'),
new Attachment('filename.html', 'text/html', '<html><body>Hello world</body></html>'),
new Attachment(
'filename.docx',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
file_get_contents(SoapServerAndSoapClientCommunicationTest::LARGE_SWA_FILE)
),
]);
return $response;
}
}

View File

@ -0,0 +1,15 @@
<?php
namespace Fixtures;
use Fixtures\Attachment\MessageWithAttachmentsTrait;
class DummyServiceMethodWithIncomingLargeSwaRequest
{
use MessageWithAttachmentsTrait;
/**
* @var int $dummyAttribute
*/
public $dummyAttribute;
}

View File

@ -0,0 +1,11 @@
<?php
namespace Fixtures;
class DummyServiceMethodWithIncomingLargeSwaResponse
{
/**
* @var bool $status
*/
public $status;
}

View File

@ -0,0 +1,11 @@
<?php
namespace Fixtures;
class DummyServiceMethodWithOutgoingLargeSwaRequest
{
/**
* @var int $dummyAttribute
*/
public $dummyAttribute;
}

View File

@ -0,0 +1,15 @@
<?php
namespace Fixtures;
use Fixtures\Attachment\MessageWithAttachmentsTrait;
class DummyServiceMethodWithOutgoingLargeSwaResponse
{
use MessageWithAttachmentsTrait;
/**
* @var bool $status
*/
public $status;
}

View File

@ -2,10 +2,12 @@
namespace Fixtures;
use Fixtures\Attachment\AttachmentCollection;
use Fixtures\Attachment\MessageWithAttachmentsTrait;
class DummyServiceRequestWithAttachments
{
use MessageWithAttachmentsTrait;
/**
* @var int $dummyAttribute
*/
@ -15,14 +17,4 @@ class DummyServiceRequestWithAttachments
* @var bool $includeAttachments
*/
public $includeAttachments;
/**
* @var AttachmentCollection $attachmentCollection
*/
public $attachmentCollection;
public function hasAttachments()
{
return $this->attachmentCollection !== null && $this->attachmentCollection->hasAttachments();
}
}

View File

@ -2,22 +2,14 @@
namespace Fixtures;
use Fixtures\Attachment\AttachmentCollection;
use Fixtures\Attachment\MessageWithAttachmentsTrait;
class DummyServiceResponseWithAttachments
{
use MessageWithAttachmentsTrait;
/**
* @var bool $status
*/
public $status;
/**
* @var AttachmentCollection $attachmentCollection
*/
public $attachmentCollection;
public function hasAttachments()
{
return $this->attachmentCollection !== null && $this->attachmentCollection->hasAttachments();
}
}

View File

@ -0,0 +1 @@
multipart/related; type="application/soap+xml"; charset=utf-8; boundary="urn:uuid:340c4456-d650-4ddb-ae83-b13cf6077326"; start="<urn:uuid:c0d48506-8780-410c-b06a-52b6bbbefa5b>"; action="DummyService.dummyServiceMethodWithIncomingLargeSwa"

View File

@ -0,0 +1,14 @@
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:sch="http://schema.testcase">
<soapenv:Header>
<sch:SoapHeader>
<user>admin</user>
</sch:SoapHeader>
</soapenv:Header>
<soapenv:Body>
<sch:dummyServiceMethodWithOutgoingLargeSwa>
<request>
<dummyAttribute>1</dummyAttribute>
</request>
</sch:dummyServiceMethodWithOutgoingLargeSwa>
</soapenv:Body>
</soapenv:Envelope>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://schema.testcase">
<SOAP-ENV:Body>
<ns1:dummyServiceMethodWithIncomingLargeSwaRequest>
<dummyServiceReturn>
<status>true</status>
</dummyServiceReturn>
</ns1:dummyServiceMethodWithIncomingLargeSwaRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Binary file not shown.

View File

@ -0,0 +1,15 @@
<?php
require_once __DIR__.'/../vendor/autoload.php';
const FIXTURES_DIR = __DIR__.'/Fixtures';
const CACHE_DIR = __DIR__.'/../cache';
if (isset($_GET['wsdl'])) {
header('Content-type: text/xml');
echo file_get_contents(FIXTURES_DIR.'/DummyService.wsdl');
exit;
}
header('Content-type: text/xml');
echo file_get_contents(FIXTURES_DIR.'/Message/Response/dummyServiceMethodWithIncomingLargeSwa.response.message');

View File

@ -0,0 +1,22 @@
<?php
const FIXTURES_DIR = __DIR__ . '/Fixtures';
if (isset($_GET['wsdl'])) {
header('Content-type: text/xml');
echo file_get_contents(FIXTURES_DIR.'/DummyService.wsdl');
exit;
}
$contentTypeFromCache = __DIR__.'/../cache/content-type-soap-server-response.xml';
$multiPartMessageFromCache = __DIR__.'/../cache/multipart-message-soap-server-response.xml';
if (file_exists($contentTypeFromCache) === false || file_exists($multiPartMessageFromCache) === false) {
$soapServer = new \SoapServer(FIXTURES_DIR.'/DummyService.wsdl');
$soapServer->fault(
911,
'Cannot load data from cache: run soap server testHandleRequestWithLargeSwaResponse to get the data.'
);
}
header('Content-type: '.file_get_contents($contentTypeFromCache));
echo file_get_contents($multiPartMessageFromCache);