MultipartStreamTest.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. <?php
  2. namespace GuzzleHttp\Tests\Psr7;
  3. use GuzzleHttp\Psr7;
  4. use GuzzleHttp\Psr7\MultipartStream;
  5. class MultipartStreamTest extends BaseTest
  6. {
  7. public function testCreatesDefaultBoundary()
  8. {
  9. $b = new MultipartStream();
  10. $this->assertNotEmpty($b->getBoundary());
  11. }
  12. public function testCanProvideBoundary()
  13. {
  14. $b = new MultipartStream([], 'foo');
  15. $this->assertEquals('foo', $b->getBoundary());
  16. }
  17. public function testIsNotWritable()
  18. {
  19. $b = new MultipartStream();
  20. $this->assertFalse($b->isWritable());
  21. }
  22. public function testCanCreateEmptyStream()
  23. {
  24. $b = new MultipartStream();
  25. $boundary = $b->getBoundary();
  26. $this->assertSame("--{$boundary}--\r\n", $b->getContents());
  27. $this->assertSame(strlen($boundary) + 6, $b->getSize());
  28. }
  29. /**
  30. * @expectedException \InvalidArgumentException
  31. */
  32. public function testValidatesFilesArrayElement()
  33. {
  34. new MultipartStream([['foo' => 'bar']]);
  35. }
  36. /**
  37. * @expectedException \InvalidArgumentException
  38. */
  39. public function testEnsuresFileHasName()
  40. {
  41. new MultipartStream([['contents' => 'bar']]);
  42. }
  43. public function testSerializesFields()
  44. {
  45. $b = new MultipartStream([
  46. [
  47. 'name' => 'foo',
  48. 'contents' => 'bar'
  49. ],
  50. [
  51. 'name' => 'baz',
  52. 'contents' => 'bam'
  53. ]
  54. ], 'boundary');
  55. $this->assertEquals(
  56. "--boundary\r\nContent-Disposition: form-data; name=\"foo\"\r\nContent-Length: 3\r\n\r\n"
  57. . "bar\r\n--boundary\r\nContent-Disposition: form-data; name=\"baz\"\r\nContent-Length: 3"
  58. . "\r\n\r\nbam\r\n--boundary--\r\n", (string) $b);
  59. }
  60. public function testSerializesNonStringFields()
  61. {
  62. $b = new MultipartStream([
  63. [
  64. 'name' => 'int',
  65. 'contents' => (int) 1
  66. ],
  67. [
  68. 'name' => 'bool',
  69. 'contents' => (boolean) false
  70. ],
  71. [
  72. 'name' => 'bool2',
  73. 'contents' => (boolean) true
  74. ],
  75. [
  76. 'name' => 'float',
  77. 'contents' => (float) 1.1
  78. ]
  79. ], 'boundary');
  80. $this->assertEquals(
  81. "--boundary\r\nContent-Disposition: form-data; name=\"int\"\r\nContent-Length: 1\r\n\r\n"
  82. . "1\r\n--boundary\r\nContent-Disposition: form-data; name=\"bool\"\r\n\r\n\r\n--boundary"
  83. . "\r\nContent-Disposition: form-data; name=\"bool2\"\r\nContent-Length: 1\r\n\r\n"
  84. . "1\r\n--boundary\r\nContent-Disposition: form-data; name=\"float\"\r\nContent-Length: 3"
  85. . "\r\n\r\n1.1\r\n--boundary--\r\n", (string) $b);
  86. }
  87. public function testSerializesFiles()
  88. {
  89. $f1 = Psr7\FnStream::decorate(Psr7\stream_for('foo'), [
  90. 'getMetadata' => function () {
  91. return '/foo/bar.txt';
  92. }
  93. ]);
  94. $f2 = Psr7\FnStream::decorate(Psr7\stream_for('baz'), [
  95. 'getMetadata' => function () {
  96. return '/foo/baz.jpg';
  97. }
  98. ]);
  99. $f3 = Psr7\FnStream::decorate(Psr7\stream_for('bar'), [
  100. 'getMetadata' => function () {
  101. return '/foo/bar.gif';
  102. }
  103. ]);
  104. $b = new MultipartStream([
  105. [
  106. 'name' => 'foo',
  107. 'contents' => $f1
  108. ],
  109. [
  110. 'name' => 'qux',
  111. 'contents' => $f2
  112. ],
  113. [
  114. 'name' => 'qux',
  115. 'contents' => $f3
  116. ],
  117. ], 'boundary');
  118. $expected = <<<EOT
  119. --boundary
  120. Content-Disposition: form-data; name="foo"; filename="bar.txt"
  121. Content-Length: 3
  122. Content-Type: text/plain
  123. foo
  124. --boundary
  125. Content-Disposition: form-data; name="qux"; filename="baz.jpg"
  126. Content-Length: 3
  127. Content-Type: image/jpeg
  128. baz
  129. --boundary
  130. Content-Disposition: form-data; name="qux"; filename="bar.gif"
  131. Content-Length: 3
  132. Content-Type: image/gif
  133. bar
  134. --boundary--
  135. EOT;
  136. $this->assertEquals($expected, str_replace("\r", '', $b));
  137. }
  138. public function testSerializesFilesWithCustomHeaders()
  139. {
  140. $f1 = Psr7\FnStream::decorate(Psr7\stream_for('foo'), [
  141. 'getMetadata' => function () {
  142. return '/foo/bar.txt';
  143. }
  144. ]);
  145. $b = new MultipartStream([
  146. [
  147. 'name' => 'foo',
  148. 'contents' => $f1,
  149. 'headers' => [
  150. 'x-foo' => 'bar',
  151. 'content-disposition' => 'custom'
  152. ]
  153. ]
  154. ], 'boundary');
  155. $expected = <<<EOT
  156. --boundary
  157. x-foo: bar
  158. content-disposition: custom
  159. Content-Length: 3
  160. Content-Type: text/plain
  161. foo
  162. --boundary--
  163. EOT;
  164. $this->assertEquals($expected, str_replace("\r", '', $b));
  165. }
  166. public function testSerializesFilesWithCustomHeadersAndMultipleValues()
  167. {
  168. $f1 = Psr7\FnStream::decorate(Psr7\stream_for('foo'), [
  169. 'getMetadata' => function () {
  170. return '/foo/bar.txt';
  171. }
  172. ]);
  173. $f2 = Psr7\FnStream::decorate(Psr7\stream_for('baz'), [
  174. 'getMetadata' => function () {
  175. return '/foo/baz.jpg';
  176. }
  177. ]);
  178. $b = new MultipartStream([
  179. [
  180. 'name' => 'foo',
  181. 'contents' => $f1,
  182. 'headers' => [
  183. 'x-foo' => 'bar',
  184. 'content-disposition' => 'custom'
  185. ]
  186. ],
  187. [
  188. 'name' => 'foo',
  189. 'contents' => $f2,
  190. 'headers' => ['cOntenT-Type' => 'custom'],
  191. ]
  192. ], 'boundary');
  193. $expected = <<<EOT
  194. --boundary
  195. x-foo: bar
  196. content-disposition: custom
  197. Content-Length: 3
  198. Content-Type: text/plain
  199. foo
  200. --boundary
  201. cOntenT-Type: custom
  202. Content-Disposition: form-data; name="foo"; filename="baz.jpg"
  203. Content-Length: 3
  204. baz
  205. --boundary--
  206. EOT;
  207. $this->assertEquals($expected, str_replace("\r", '', $b));
  208. }
  209. }