From ae2a8b8502ac695d5accab01355b184921cb1999 Mon Sep 17 00:00:00 2001 From: Chris Lloyd Date: Mon, 28 Feb 2022 10:10:26 +0000 Subject: [PATCH] WIP --- src/Controller/Transaction.php | 6 +- src/PathSegment/Batch.php | 2 +- src/Transaction/MediaType.php | 22 +++++- src/Transaction/MultipartDocument.php | 2 +- tests/Entity/EntityTest.php | 19 +---- tests/Entity/FilesystemTest.php | 10 +-- tests/Protocol/MediaTypeTest.php | 72 +++++++++++++++++++ tests/Queries/ValueTest.php | 61 ++++++++++++++++ ...lectionTest__test_raw_custom_accept__1.yml | 5 -- ...lectionTest__test_raw_custom_format__1.yml | 5 -- ...lectionTest__test_raw_custom_accept__1.yml | 5 -- ...lectionTest__test_raw_custom_format__1.yml | 5 -- .../RedisTest__test_raw_custom_accept__1.yml | 5 -- .../RedisTest__test_raw_custom_format__1.yml | 5 -- .../SQLTest__test_raw_custom_accept__1.yml | 5 -- .../SQLTest__test_raw_custom_format__1.yml | 5 -- ...ingTest__test_stream_buffered_error__2.yml | 4 -- .../ValueTest__test_raw_accept_any__1.yml} | 2 +- .../ValueTest__test_raw_custom_accept__1.yml} | 0 .../ValueTest__test_raw_custom_format__1.yml} | 0 .../ValueTest__test_raw_no_accept__1.yml} | 2 +- 21 files changed, 167 insertions(+), 75 deletions(-) create mode 100644 tests/Protocol/MediaTypeTest.php create mode 100644 tests/Queries/ValueTest.php delete mode 100644 tests/__snapshots__/Entity/KeyedCollectionTest__test_raw_custom_accept__1.yml delete mode 100644 tests/__snapshots__/Entity/KeyedCollectionTest__test_raw_custom_format__1.yml delete mode 100644 tests/__snapshots__/Entity/NumericCollectionTest__test_raw_custom_accept__1.yml delete mode 100644 tests/__snapshots__/Entity/NumericCollectionTest__test_raw_custom_format__1.yml delete mode 100644 tests/__snapshots__/Entity/RedisTest__test_raw_custom_accept__1.yml delete mode 100644 tests/__snapshots__/Entity/RedisTest__test_raw_custom_format__1.yml delete mode 100644 tests/__snapshots__/Entity/SQLTest__test_raw_custom_accept__1.yml delete mode 100644 tests/__snapshots__/Entity/SQLTest__test_raw_custom_format__1.yml delete mode 100644 tests/__snapshots__/Protocol/ErrorReportingTest__test_stream_buffered_error__2.yml rename tests/__snapshots__/{Entity/EloquentTest__test_raw_custom_accept__1.yml => Queries/ValueTest__test_raw_accept_any__1.yml} (66%) rename tests/__snapshots__/{Entity/CSVTest__test_raw_custom_accept__1.yml => Queries/ValueTest__test_raw_custom_accept__1.yml} (100%) rename tests/__snapshots__/{Entity/CSVTest__test_raw_custom_format__1.yml => Queries/ValueTest__test_raw_custom_format__1.yml} (100%) rename tests/__snapshots__/{Entity/EloquentTest__test_raw_custom_format__1.yml => Queries/ValueTest__test_raw_no_accept__1.yml} (66%) diff --git a/src/Controller/Transaction.php b/src/Controller/Transaction.php index ae22048cf..6c647379f 100644 --- a/src/Controller/Transaction.php +++ b/src/Controller/Transaction.php @@ -1167,7 +1167,7 @@ public function process(): ResponseInterface break; case '$value': - $providedTypes = MediaTypes::factory(MediaType::any); + $providedTypes = MediaTypes::factory(MediaType::text, MediaType::any); break; default: @@ -1196,6 +1196,10 @@ public function process(): ResponseInterface $this->version ); + if ('text' === $acceptedType->getType() && !$acceptedType->hasParameter(Constants::charset)) { + $acceptedType->setParameter(Constants::charset, 'utf-8'); + } + if ('json' === $acceptedType->getSubtype()) { $acceptedType->setParameter( $this->version->prefixParameter(Constants::metadata), diff --git a/src/PathSegment/Batch.php b/src/PathSegment/Batch.php index e91d8babc..6ad2ef6af 100644 --- a/src/PathSegment/Batch.php +++ b/src/PathSegment/Batch.php @@ -46,7 +46,7 @@ public static function pipe( $contentType = $transaction->getProvidedContentType(); - switch ($contentType->getType()) { + switch ($contentType->getFullType()) { case MediaType::multipartMixed: return new Batch\Multipart(); diff --git a/src/Transaction/MediaType.php b/src/Transaction/MediaType.php index 3f3eb5819..cc8a708a5 100644 --- a/src/Transaction/MediaType.php +++ b/src/Transaction/MediaType.php @@ -4,9 +4,6 @@ namespace Flat3\Lodata\Transaction; -use Flat3\Lodata\Exception\Protocol\NotAcceptableException; -use Flat3\Lodata\Helper\Constants; - /** * Media Type * @link https://tools.ietf.org/html/rfc2045 @@ -98,6 +95,16 @@ public function getParameter(string $key): ?string return $this->parameter->getParameter($key); } + /** + * Check whether the type has the provided parameter + * @param string $key Parameter + * @return bool + */ + public function hasParameter(string $key): bool + { + return null !== $this->getParameter($key); + } + /** * Get all parameter keys in the media type * @return array @@ -112,6 +119,15 @@ public function getParameterKeys() * @return string */ public function getType(): string + { + return $this->type; + } + + /** + * Get the type with subtype + * @return string + */ + public function getFullType(): string { return $this->type.'/'.$this->subtype; } diff --git a/src/Transaction/MultipartDocument.php b/src/Transaction/MultipartDocument.php index cafbc500b..4d5d46304 100644 --- a/src/Transaction/MultipartDocument.php +++ b/src/Transaction/MultipartDocument.php @@ -72,7 +72,7 @@ public function setBody(string $body): self { $this->body = $body; - if ($this->getContentType()->getType() === MediaType::multipartMixed) { + if ($this->getContentType()->getFullType() === MediaType::multipartMixed) { $this->parseDocuments(); } diff --git a/tests/Entity/EntityTest.php b/tests/Entity/EntityTest.php index 986e2aeb5..216131bff 100644 --- a/tests/Entity/EntityTest.php +++ b/tests/Entity/EntityTest.php @@ -9,6 +9,7 @@ use Flat3\Lodata\GeneratedProperty; use Flat3\Lodata\Tests\Helpers\Request; use Flat3\Lodata\Tests\TestCase; +use Flat3\Lodata\Transaction\MediaType; use Flat3\Lodata\Transaction\MetadataType; use Flat3\Lodata\Type; use Flat3\Lodata\Type\Int32; @@ -303,24 +304,6 @@ public function test_null_raw_no_content() ); } - public function test_raw_custom_accept() - { - $this->assertResponseSnapshot( - (new Request) - ->header('accept', 'application/octet-stream') - ->path($this->entityPath.'/name/$value') - ); - } - - public function test_raw_custom_format() - { - $this->assertResponseSnapshot( - (new Request) - ->format('application/octet-stream') - ->path($this->entityPath.'/name/$value') - ); - } - public function test_not_entity_or_set_not_found() { $this->assertNotFound( diff --git a/tests/Entity/FilesystemTest.php b/tests/Entity/FilesystemTest.php index f67eaf1e1..282637c99 100644 --- a/tests/Entity/FilesystemTest.php +++ b/tests/Entity/FilesystemTest.php @@ -110,23 +110,23 @@ public function test_null_raw_no_content() { } - public function test_raw_custom_accept() + public function test_read_alternative_key() { } - public function test_raw_custom_format() + public function test_read_collection_property() { } - public function test_read_alternative_key() + public function test_raw() { } - public function test_read_collection_property() + public function test_raw_no_accept() { } - public function test_raw() + public function test_raw_accept_any() { } diff --git a/tests/Protocol/MediaTypeTest.php b/tests/Protocol/MediaTypeTest.php new file mode 100644 index 000000000..8cc0626c3 --- /dev/null +++ b/tests/Protocol/MediaTypeTest.php @@ -0,0 +1,72 @@ + 'UTF-8'], + ], + [ + 'multipart/mixed;param=true', + 'multipart/mixed;param=true', + 'multipart', + 'mixed', + ['param' => 'true'], + ], + [ + 'multipart/mixed; param=true', + 'multipart/mixed;param=true', + 'multipart', + 'mixed', + ['param' => 'true'], + ], + [ + 'multipart/mixed; param=true; this=false', + 'multipart/mixed;param=true;this=false', + 'multipart', + 'mixed', + ['param' => 'true', 'this' => 'false'], + ], + ]; + } + + /** + * @dataProvider typeProvider + */ + public function test_types( + string $original, + string $normalised, + string $type, + string $subtype, + array $parameters = [] + ) { + $mt = (new MediaType)->parse($original); + $this->assertEquals($type, $mt->getType()); + $this->assertEquals($subtype, $mt->getSubtype()); + + foreach ($parameters as $key => $value) { + $this->assertEquals($value, $mt->getParameter($key)); + } + + $this->assertEquals($normalised, (string) $mt); + } +} \ No newline at end of file diff --git a/tests/Queries/ValueTest.php b/tests/Queries/ValueTest.php new file mode 100644 index 000000000..e0bbdf92f --- /dev/null +++ b/tests/Queries/ValueTest.php @@ -0,0 +1,61 @@ +addDeclaredProperty('sprop', Type::string()); + $entity = new Singleton('stest', $type); + $entity['sprop'] = 'svalue'; + Lodata::add($entity); + } + + public function test_raw_custom_accept() + { + $this->assertResponseSnapshot( + (new Request) + ->header('accept', 'application/octet-stream') + ->path('/stest/sprop/$value') + ); + } + + public function test_raw_custom_format() + { + $this->assertResponseSnapshot( + (new Request) + ->format('application/octet-stream') + ->path('/stest/sprop/$value') + ); + } + + public function test_raw_no_accept() + { + $this->assertResponseSnapshot( + (new Request) + ->accept('') + ->path('/stest/sprop/$value') + ); + } + + public function test_raw_accept_any() + { + $this->assertResponseSnapshot( + (new Request) + ->accept(MediaType::any) + ->path('/stest/sprop/$value') + ); + } +} \ No newline at end of file diff --git a/tests/__snapshots__/Entity/KeyedCollectionTest__test_raw_custom_accept__1.yml b/tests/__snapshots__/Entity/KeyedCollectionTest__test_raw_custom_accept__1.yml deleted file mode 100644 index 97d7da8d6..000000000 --- a/tests/__snapshots__/Entity/KeyedCollectionTest__test_raw_custom_accept__1.yml +++ /dev/null @@ -1,5 +0,0 @@ -headers: - cache-control: ['no-cache, private'] - content-type: [application/octet-stream] - odata-version: ['4.01'] -status: 200 diff --git a/tests/__snapshots__/Entity/KeyedCollectionTest__test_raw_custom_format__1.yml b/tests/__snapshots__/Entity/KeyedCollectionTest__test_raw_custom_format__1.yml deleted file mode 100644 index 97d7da8d6..000000000 --- a/tests/__snapshots__/Entity/KeyedCollectionTest__test_raw_custom_format__1.yml +++ /dev/null @@ -1,5 +0,0 @@ -headers: - cache-control: ['no-cache, private'] - content-type: [application/octet-stream] - odata-version: ['4.01'] -status: 200 diff --git a/tests/__snapshots__/Entity/NumericCollectionTest__test_raw_custom_accept__1.yml b/tests/__snapshots__/Entity/NumericCollectionTest__test_raw_custom_accept__1.yml deleted file mode 100644 index 97d7da8d6..000000000 --- a/tests/__snapshots__/Entity/NumericCollectionTest__test_raw_custom_accept__1.yml +++ /dev/null @@ -1,5 +0,0 @@ -headers: - cache-control: ['no-cache, private'] - content-type: [application/octet-stream] - odata-version: ['4.01'] -status: 200 diff --git a/tests/__snapshots__/Entity/NumericCollectionTest__test_raw_custom_format__1.yml b/tests/__snapshots__/Entity/NumericCollectionTest__test_raw_custom_format__1.yml deleted file mode 100644 index 97d7da8d6..000000000 --- a/tests/__snapshots__/Entity/NumericCollectionTest__test_raw_custom_format__1.yml +++ /dev/null @@ -1,5 +0,0 @@ -headers: - cache-control: ['no-cache, private'] - content-type: [application/octet-stream] - odata-version: ['4.01'] -status: 200 diff --git a/tests/__snapshots__/Entity/RedisTest__test_raw_custom_accept__1.yml b/tests/__snapshots__/Entity/RedisTest__test_raw_custom_accept__1.yml deleted file mode 100644 index 97d7da8d6..000000000 --- a/tests/__snapshots__/Entity/RedisTest__test_raw_custom_accept__1.yml +++ /dev/null @@ -1,5 +0,0 @@ -headers: - cache-control: ['no-cache, private'] - content-type: [application/octet-stream] - odata-version: ['4.01'] -status: 200 diff --git a/tests/__snapshots__/Entity/RedisTest__test_raw_custom_format__1.yml b/tests/__snapshots__/Entity/RedisTest__test_raw_custom_format__1.yml deleted file mode 100644 index 97d7da8d6..000000000 --- a/tests/__snapshots__/Entity/RedisTest__test_raw_custom_format__1.yml +++ /dev/null @@ -1,5 +0,0 @@ -headers: - cache-control: ['no-cache, private'] - content-type: [application/octet-stream] - odata-version: ['4.01'] -status: 200 diff --git a/tests/__snapshots__/Entity/SQLTest__test_raw_custom_accept__1.yml b/tests/__snapshots__/Entity/SQLTest__test_raw_custom_accept__1.yml deleted file mode 100644 index 97d7da8d6..000000000 --- a/tests/__snapshots__/Entity/SQLTest__test_raw_custom_accept__1.yml +++ /dev/null @@ -1,5 +0,0 @@ -headers: - cache-control: ['no-cache, private'] - content-type: [application/octet-stream] - odata-version: ['4.01'] -status: 200 diff --git a/tests/__snapshots__/Entity/SQLTest__test_raw_custom_format__1.yml b/tests/__snapshots__/Entity/SQLTest__test_raw_custom_format__1.yml deleted file mode 100644 index 97d7da8d6..000000000 --- a/tests/__snapshots__/Entity/SQLTest__test_raw_custom_format__1.yml +++ /dev/null @@ -1,5 +0,0 @@ -headers: - cache-control: ['no-cache, private'] - content-type: [application/octet-stream] - odata-version: ['4.01'] -status: 200 diff --git a/tests/__snapshots__/Protocol/ErrorReportingTest__test_stream_buffered_error__2.yml b/tests/__snapshots__/Protocol/ErrorReportingTest__test_stream_buffered_error__2.yml deleted file mode 100644 index 8a80db80d..000000000 --- a/tests/__snapshots__/Protocol/ErrorReportingTest__test_stream_buffered_error__2.yml +++ /dev/null @@ -1,4 +0,0 @@ -headers: - cache-control: ['no-cache, private'] - content-type: [application/json] -status: 501 diff --git a/tests/__snapshots__/Entity/EloquentTest__test_raw_custom_accept__1.yml b/tests/__snapshots__/Queries/ValueTest__test_raw_accept_any__1.yml similarity index 66% rename from tests/__snapshots__/Entity/EloquentTest__test_raw_custom_accept__1.yml rename to tests/__snapshots__/Queries/ValueTest__test_raw_accept_any__1.yml index 97d7da8d6..243211c55 100644 --- a/tests/__snapshots__/Entity/EloquentTest__test_raw_custom_accept__1.yml +++ b/tests/__snapshots__/Queries/ValueTest__test_raw_accept_any__1.yml @@ -1,5 +1,5 @@ headers: cache-control: ['no-cache, private'] - content-type: [application/octet-stream] + content-type: [text/plain;charset=utf-8] odata-version: ['4.01'] status: 200 diff --git a/tests/__snapshots__/Entity/CSVTest__test_raw_custom_accept__1.yml b/tests/__snapshots__/Queries/ValueTest__test_raw_custom_accept__1.yml similarity index 100% rename from tests/__snapshots__/Entity/CSVTest__test_raw_custom_accept__1.yml rename to tests/__snapshots__/Queries/ValueTest__test_raw_custom_accept__1.yml diff --git a/tests/__snapshots__/Entity/CSVTest__test_raw_custom_format__1.yml b/tests/__snapshots__/Queries/ValueTest__test_raw_custom_format__1.yml similarity index 100% rename from tests/__snapshots__/Entity/CSVTest__test_raw_custom_format__1.yml rename to tests/__snapshots__/Queries/ValueTest__test_raw_custom_format__1.yml diff --git a/tests/__snapshots__/Entity/EloquentTest__test_raw_custom_format__1.yml b/tests/__snapshots__/Queries/ValueTest__test_raw_no_accept__1.yml similarity index 66% rename from tests/__snapshots__/Entity/EloquentTest__test_raw_custom_format__1.yml rename to tests/__snapshots__/Queries/ValueTest__test_raw_no_accept__1.yml index 97d7da8d6..243211c55 100644 --- a/tests/__snapshots__/Entity/EloquentTest__test_raw_custom_format__1.yml +++ b/tests/__snapshots__/Queries/ValueTest__test_raw_no_accept__1.yml @@ -1,5 +1,5 @@ headers: cache-control: ['no-cache, private'] - content-type: [application/octet-stream] + content-type: [text/plain;charset=utf-8] odata-version: ['4.01'] status: 200