110 lines
4.4 KiB
PHP
110 lines
4.4 KiB
PHP
<?php
|
|
// HttpFormContentTest.php
|
|
// Created: 2025-03-12
|
|
// Updated: 2025-03-12
|
|
|
|
declare(strict_types=1);
|
|
|
|
use PHPUnit\Framework\TestCase;
|
|
use PHPUnit\Framework\Attributes\{CoversClass,DataProvider,UsesClass};
|
|
use Index\Http\Content\{MultipartFormContent,UrlEncodedFormContent};
|
|
use Index\Http\Content\Multipart\{FileMultipartFormData,ValueMultipartFormData};
|
|
use Index\Http\Streams\Stream;
|
|
|
|
#[CoversClass(MultipartFormContent::class)]
|
|
#[CoversClass(UrlEncodedFormContent::class)]
|
|
#[CoversClass(FileMultipartFormData::class)]
|
|
#[CoversClass(ValueMultipartFormData::class)]
|
|
#[UsesClass(Stream::class)]
|
|
final class HttpFormContentTest extends TestCase {
|
|
/** @return array<array{0: string, 1: array<string, list<?string>>}> */
|
|
public static function urlEncodedStringProvider(): array {
|
|
return [
|
|
[
|
|
'username=meow&password=beans',
|
|
['username' => ['meow'], 'password' => ['beans']]
|
|
],
|
|
[
|
|
'username=meow&password=beans&password=soap',
|
|
['username' => ['meow'], 'password' => ['beans', 'soap']]
|
|
],
|
|
[
|
|
'arg&arg&arg=maybe&arg&the=ok',
|
|
['arg' => [null, null, 'maybe', null], 'the' => ['ok']]
|
|
],
|
|
[
|
|
'array[]=old&array%5B%5D=syntax&array[meow]=soup',
|
|
['array[]' => ['old', 'syntax'], 'array[meow]' => ['soup']]
|
|
],
|
|
[
|
|
'plus=this+one+uses+plus+as+space&twenty=this%20uses%20percent%20encoding',
|
|
['plus' => ['this one uses plus as space'], 'twenty' => ['this uses percent encoding']]
|
|
],
|
|
[
|
|
'&&=&&=&', // there's no reason why this shouldn't be valid but it is quirky!
|
|
['' => [null, null, '', null, '', null]]
|
|
],
|
|
[
|
|
'',
|
|
[]
|
|
],
|
|
[
|
|
' ',
|
|
[' ' => [null]]
|
|
],
|
|
];
|
|
}
|
|
|
|
/** @param array<string, string[]> $expected */
|
|
#[DataProvider('urlEncodedStringProvider')]
|
|
public function testUrlEncodedForm(string $formString, array $expected): void {
|
|
$form = UrlEncodedFormContent::parseStream(Stream::createStream($formString));
|
|
|
|
$this->assertFalse($form->hasParam('never_has_this'));
|
|
$this->assertEquals(0, $form->getParamCount('never_has_this_either'));
|
|
$this->assertNull($form->getParam('this_is_not_there_either'));
|
|
$this->assertEquals(0401, $form->getParamAt('abusing_octal_notation_for_teto_reference', 3510, default: 0401));
|
|
|
|
foreach($expected as $key => $values) {
|
|
$this->assertTrue($form->hasParam($key));
|
|
$this->assertEquals($form->getParam($key), $values[0] ?? null);
|
|
|
|
$count = $form->getParamCount($key);
|
|
$this->assertEquals(count($values), $count);
|
|
|
|
for($i = 0; $i < $count; ++$i)
|
|
$this->assertEquals($form->getParamAt($key, $i), $values[$i]);
|
|
}
|
|
}
|
|
|
|
public function testMultipartForm(): void {
|
|
$form = MultipartFormContent::parseStream(
|
|
Stream::createStreamFromFile(__DIR__ . '/HttpFormContentTest-multipart.bin', 'rb'),
|
|
'----geckoformboundaryc23c64d876d81ed7258ada21a9eb0b06'
|
|
);
|
|
|
|
// normal form api
|
|
$this->assertFalse($form->hasParam('never_has_this'));
|
|
$this->assertEquals(0, $form->getParamCount('never_has_this_either'));
|
|
$this->assertNull($form->getParam('this_is_not_there_either'));
|
|
$this->assertEquals(0401, $form->getParamAt('abusing_octal_notation_for_teto_reference', 3510, default: 0401));
|
|
|
|
$this->assertTrue($form->hasParam('meow'));
|
|
$this->assertEquals(1, $form->getParamCount('meow'));
|
|
$this->assertEquals('sfdsfs', $form->getParam('meow'));
|
|
|
|
$this->assertTrue($form->hasParam('mewow'));
|
|
$this->assertEquals(1, $form->getParamCount('mewow'));
|
|
$this->assertEquals('https://railgun.sh/sockchat', $form->getParam('mewow'));
|
|
|
|
$this->assertTrue($form->hasParam('"the'));
|
|
$this->assertEquals(2, $form->getParamCount('"the'));
|
|
$this->assertEquals('value!', $form->getParam('"the'));
|
|
$secondValue = $form->getParamAt('"the', 1);
|
|
$this->assertIsString($secondValue);
|
|
$this->assertEquals('8e3b3df1ab6be7498566e795cc9fe3b8f55e084d0e1fcf3e5323269cfc1bc884', hash('sha256', $secondValue));
|
|
|
|
// multipart specific api
|
|
// tbd
|
|
}
|
|
}
|