|
19 | 19 | use CodeIgniter\Exceptions\InvalidArgumentException; |
20 | 20 | use CodeIgniter\HTTP\Exceptions\HTTPException; |
21 | 21 | use CodeIgniter\HTTP\Files\UploadedFile; |
| 22 | +use CodeIgniter\Input\InputData; |
22 | 23 | use CodeIgniter\Superglobals; |
23 | 24 | use CodeIgniter\Test\CIUnitTestCase; |
24 | 25 | use Config\App; |
@@ -86,6 +87,35 @@ public function testCanGrabPostVars(): void |
86 | 87 | $this->assertNull($this->request->getPost('TESTY')); |
87 | 88 | } |
88 | 89 |
|
| 90 | + public function testGetQueryInputReadsQueryData(): void |
| 91 | + { |
| 92 | + service('superglobals')->setGet('page', '3'); |
| 93 | + service('superglobals')->setGet('filters', ['active' => 'true']); |
| 94 | + service('superglobals')->setPost('page', '10'); |
| 95 | + |
| 96 | + $request = $this->createRequest(); |
| 97 | + $input = $request->getQueryInput(); |
| 98 | + |
| 99 | + $this->assertInstanceOf(InputData::class, $input); |
| 100 | + $this->assertSame(3, $input->integer('page')); |
| 101 | + $this->assertTrue($input->boolean('filters.active')); |
| 102 | + $this->assertSame(1, $input->integer('missing', 1)); |
| 103 | + } |
| 104 | + |
| 105 | + public function testGetPostInputReadsPostData(): void |
| 106 | + { |
| 107 | + service('superglobals')->setGet('remember', '0'); |
| 108 | + service('superglobals')->setPost('remember', '1'); |
| 109 | + service('superglobals')->setPost('tags', ['php', 'ci4']); |
| 110 | + |
| 111 | + $request = $this->createRequest(); |
| 112 | + $input = $request->getPostInput(); |
| 113 | + |
| 114 | + $this->assertInstanceOf(InputData::class, $input); |
| 115 | + $this->assertTrue($input->boolean('remember')); |
| 116 | + $this->assertSame(['php', 'ci4'], $input->array('tags')); |
| 117 | + } |
| 118 | + |
89 | 119 | public function testCanGrabPostBeforeGet(): void |
90 | 120 | { |
91 | 121 | service('superglobals')->setPost('TEST', '5'); |
@@ -572,6 +602,104 @@ public function testCanGrabGetRawInput(): void |
572 | 602 | $this->assertSame($expected, $request->getRawInput()); |
573 | 603 | } |
574 | 604 |
|
| 605 | + public function testGetPayloadInputReadsJsonBody(): void |
| 606 | + { |
| 607 | + $json = json_encode([ |
| 608 | + 'page' => '4', |
| 609 | + 'filters' => ['active' => 'true'], |
| 610 | + 'nullable' => null, |
| 611 | + ]); |
| 612 | + |
| 613 | + $request = $this->createRequest(new App(), $json); |
| 614 | + $request->setHeader('Content-Type', 'application/json'); |
| 615 | + |
| 616 | + $input = $request->getPayloadInput(); |
| 617 | + |
| 618 | + $this->assertInstanceOf(InputData::class, $input); |
| 619 | + $this->assertSame(4, $input->integer('page')); |
| 620 | + $this->assertTrue($input->boolean('filters.active')); |
| 621 | + $this->assertTrue($input->has('nullable')); |
| 622 | + } |
| 623 | + |
| 624 | + #[DataProvider('provideGetPayloadInputReadsRawBodyForWriteRequests')] |
| 625 | + public function testGetPayloadInputReadsRawBodyForWriteRequests(string $method): void |
| 626 | + { |
| 627 | + $request = $this->createRequest(new App(), 'title=Hello&published=1') |
| 628 | + ->withMethod($method); |
| 629 | + |
| 630 | + $input = $request->getPayloadInput(); |
| 631 | + |
| 632 | + $this->assertSame('Hello', $input->string('title')); |
| 633 | + $this->assertTrue($input->boolean('published')); |
| 634 | + } |
| 635 | + |
| 636 | + /** |
| 637 | + * @return iterable<string, array{string}> |
| 638 | + */ |
| 639 | + public static function provideGetPayloadInputReadsRawBodyForWriteRequests(): iterable |
| 640 | + { |
| 641 | + yield 'PUT' => ['PUT']; |
| 642 | + |
| 643 | + yield 'PATCH' => ['PATCH']; |
| 644 | + |
| 645 | + yield 'DELETE' => ['DELETE']; |
| 646 | + } |
| 647 | + |
| 648 | + public function testGetPayloadInputReadsPostBodyForPostRequests(): void |
| 649 | + { |
| 650 | + service('superglobals')->setGet('title', 'Query title'); |
| 651 | + service('superglobals')->setPost('title', 'Post title'); |
| 652 | + |
| 653 | + $request = $this->createRequest()->withMethod('POST'); |
| 654 | + $input = $request->getPayloadInput(); |
| 655 | + |
| 656 | + $this->assertSame('Post title', $input->string('title')); |
| 657 | + } |
| 658 | + |
| 659 | + public function testGetPayloadInputDoesNotReadQueryDataForGetRequests(): void |
| 660 | + { |
| 661 | + service('superglobals')->setGet('page', '2'); |
| 662 | + |
| 663 | + $request = $this->createRequest()->withMethod('GET'); |
| 664 | + $input = $request->getPayloadInput(); |
| 665 | + |
| 666 | + $this->assertFalse($input->has('page')); |
| 667 | + $this->assertSame(1, $input->integer('page', 1)); |
| 668 | + } |
| 669 | + |
| 670 | + public function testGetPayloadInputReturnsEmptyInputForEmptyJsonBody(): void |
| 671 | + { |
| 672 | + $request = $this->createRequest(new App()); |
| 673 | + $request->setHeader('Content-Type', 'application/json'); |
| 674 | + |
| 675 | + $input = $request->getPayloadInput(); |
| 676 | + |
| 677 | + $this->assertInstanceOf(InputData::class, $input); |
| 678 | + $this->assertFalse($input->has('name')); |
| 679 | + } |
| 680 | + |
| 681 | + public function testGetPayloadInputRejectsScalarJsonBody(): void |
| 682 | + { |
| 683 | + $this->expectException(HTTPException::class); |
| 684 | + $this->expectExceptionMessage('The provided JSON format is not supported.'); |
| 685 | + |
| 686 | + $request = $this->createRequest(new App(), '"hello"'); |
| 687 | + $request->setHeader('Content-Type', 'application/json'); |
| 688 | + |
| 689 | + $request->getPayloadInput(); |
| 690 | + } |
| 691 | + |
| 692 | + public function testGetPayloadInputKeepsInvalidJsonError(): void |
| 693 | + { |
| 694 | + $this->expectException(HTTPException::class); |
| 695 | + $this->expectExceptionMessage('Failed to parse JSON string. Error: Syntax error'); |
| 696 | + |
| 697 | + $request = $this->createRequest(new App(), 'Invalid JSON string'); |
| 698 | + $request->setHeader('Content-Type', 'application/json'); |
| 699 | + |
| 700 | + $request->getPayloadInput(); |
| 701 | + } |
| 702 | + |
575 | 703 | /** |
576 | 704 | * @param string $rawstring |
577 | 705 | * @param mixed $var |
|
0 commit comments