From a99cf6dbfdcc3e6c55c52ebe6c80368503c5b2e5 Mon Sep 17 00:00:00 2001 From: Gabriel Omar Cotelli Date: Wed, 10 Aug 2022 15:32:33 -0300 Subject: [PATCH 1/2] Use the correct media type to calculate the ETag when comparing for an update operation Fixes #164 --- .../PetOrdersRESTfulControllerTest.class.st | 44 +++++++++++++++++++ .../PetOrdersRESTfulController.class.st | 2 + ...rmediaDrivenRESTfulRequestHandler.class.st | 4 +- .../RESTfulRequestHandlerBehavior.class.st | 29 +++++++++--- .../RESTfulRequestHandlerBuilder.class.st | 2 +- 5 files changed, 72 insertions(+), 9 deletions(-) diff --git a/source/Stargate-Examples-Tests/PetOrdersRESTfulControllerTest.class.st b/source/Stargate-Examples-Tests/PetOrdersRESTfulControllerTest.class.st index 0f506f8..d2e51fd 100644 --- a/source/Stargate-Examples-Tests/PetOrdersRESTfulControllerTest.class.st +++ b/source/Stargate-Examples-Tests/PetOrdersRESTfulControllerTest.class.st @@ -550,3 +550,47 @@ PetOrdersRESTfulControllerTest >> testUpdateComment [ assert: response contents equals: '- Hola!- Mr. DJ' expandMacros ] ] + +{ #category : #'tests - comments' } +PetOrdersRESTfulControllerTest >> testUpdateCommentAcceptingADifferentMediaType [ + + "Test for https://github.com/ba-st/Stargate/issues/164" + + self withJsonFromContentsIn: self createOrder do: [ :order | + | response knownETag updateRequest | + knownETag := (self + createCommentFor: order + identifiedBy: 1 + withContent: 'Hey!') entityTag. + self createCommentFor: order identifiedBy: 1 withContent: 'Mr. DJ'. + updateRequest := self + requestToPUTComment: 'Hola!' + on: order links comments + at: 1 + forOrder: 1 + conditionalTo: knownETag. + updateRequest setAccept: ZnMimeType applicationJson. + + response := resourceController + updateOrderCommentBasedOn: updateRequest + within: self newHttpRequestContext. + + self + assert: response isSuccess; + deny: response entityTag equals: knownETag; + withJsonFromContentsIn: response + do: [ :json | self assert: json equals: 'Hola!' ]. + + response := resourceController + orderCommentsBasedOn: (self + requestToGETSubresource: order links comments + identifiedBy: 1 + accepting: ZnMimeType applicationJson) + within: self newHttpRequestContext. + + self + assert: response isSuccess; + assert: response contentType equals: ZnMimeType applicationJson; + withJsonFromContentsIn: response + do: [ :json | self assert: json equals: #( 'Hola!' 'Mr. DJ' ) ] ] +] diff --git a/source/Stargate-Examples/PetOrdersRESTfulController.class.st b/source/Stargate-Examples/PetOrdersRESTfulController.class.st index 4f7396f..b5bc0c7 100644 --- a/source/Stargate-Examples/PetOrdersRESTfulController.class.st +++ b/source/Stargate-Examples/PetOrdersRESTfulController.class.st @@ -298,6 +298,8 @@ PetOrdersRESTfulController >> initializeCommentsRequestHandler [ whenAccepting: ZnMimeType textPlain decodeApplying: [ :comment | comment ]; whenResponding: ZnMimeType textPlain encodeApplying: [ :resource | self encodeComments: resource ]; + whenResponding: ZnMimeType applicationJson + encodeToJsonApplying: [ :resource :context :writer | ]; createEntityTagHashingEncodedResource; directCachingWith: [ :caching | caching diff --git a/source/Stargate-Model/HypermediaDrivenRESTfulRequestHandler.class.st b/source/Stargate-Model/HypermediaDrivenRESTfulRequestHandler.class.st index 79e8758..9360f21 100644 --- a/source/Stargate-Model/HypermediaDrivenRESTfulRequestHandler.class.st +++ b/source/Stargate-Model/HypermediaDrivenRESTfulRequestHandler.class.st @@ -26,10 +26,10 @@ HypermediaDrivenRESTfulRequestHandler class >> resourceLocator: aResouceLocator ] { #category : #private } -HypermediaDrivenRESTfulRequestHandler >> encodeResource: resource within: requestContext [ +HypermediaDrivenRESTfulRequestHandler >> encodeResource: resource as: mediaType within: requestContext [ self holdResource: resource controlsWithin: requestContext. - ^ super encodeResource: resource within: requestContext + ^ super encodeResource: resource as: mediaType within: requestContext ] { #category : #private } diff --git a/source/Stargate-Model/RESTfulRequestHandlerBehavior.class.st b/source/Stargate-Model/RESTfulRequestHandlerBehavior.class.st index b07bf44..56ef288 100644 --- a/source/Stargate-Model/RESTfulRequestHandlerBehavior.class.st +++ b/source/Stargate-Model/RESTfulRequestHandlerBehavior.class.st @@ -45,21 +45,38 @@ RESTfulRequestHandlerBehavior >> decode: httpRequest within: requestContext [ ] { #category : #'decoding/encoding' } -RESTfulRequestHandlerBehavior >> encode: resource within: requestContext [ +RESTfulRequestHandlerBehavior >> encode: resource as: targetMediaType within: requestContext [ | encodingRule | - - encodingRule := encodingRules - at: requestContext targetMediaType - ifAbsent: [ HTTPClientError unsupportedMediaType signal: 'Encoder not found for given media type' ]. + encodingRule := encodingRules at: targetMediaType ifAbsent: [ + HTTPClientError unsupportedMediaType signal: + 'Encoder not found for given media type' ]. ^ encodingRule encode: resource within: requestContext ] +{ #category : #'decoding/encoding' } +RESTfulRequestHandlerBehavior >> encode: resource within: requestContext [ + + ^ self + encode: resource + as: requestContext targetMediaType + within: requestContext +] + +{ #category : #private } +RESTfulRequestHandlerBehavior >> encodeResource: resource as: mediaType within: requestContext [ + + ^ self encode: resource as: mediaType within: requestContext +] + { #category : #private } RESTfulRequestHandlerBehavior >> encodeResource: resource within: requestContext [ - ^ self encode: resource within: requestContext + ^ self + encodeResource: resource + as: requestContext targetMediaType + within: requestContext ] { #category : #private } diff --git a/source/Stargate-Model/RESTfulRequestHandlerBuilder.class.st b/source/Stargate-Model/RESTfulRequestHandlerBuilder.class.st index 29aa7dd..f577619 100644 --- a/source/Stargate-Model/RESTfulRequestHandlerBuilder.class.st +++ b/source/Stargate-Model/RESTfulRequestHandlerBuilder.class.st @@ -83,7 +83,7 @@ RESTfulRequestHandlerBuilder >> createEntityTagHashingEncodedResource [ self createEntityTagWith: [ :resource :mediaType :requestContext :requestHandler | EntityTagHasher new - include: ( requestHandler encodeResource: resource within: requestContext ); + include: ( requestHandler encodeResource: resource as: mediaType within: requestContext ); calculateHash ] ] From 683bb24e77195d428774d0ea5e04f420f6cfaf86 Mon Sep 17 00:00:00 2001 From: Gabriel Omar Cotelli Date: Wed, 10 Aug 2022 15:45:35 -0300 Subject: [PATCH 2/2] Do not fail fast unit tests --- .github/workflows/unit-tests.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 2af3254..f625caf 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -6,6 +6,7 @@ jobs: unit-tests: runs-on: ubuntu-latest strategy: + fail-fast: false matrix: smalltalk: [ Pharo64-10, Pharo64-9.0, Pharo64-8.0 ] name: ${{ matrix.smalltalk }}