Skip to content

Commit

Permalink
Merge pull request #165 from ba-st/164-In-some-specific-cases-412Prec…
Browse files Browse the repository at this point in the history
…ondition-Failed-responses-are-generated-for-valid-ETags

Use the correct media type to calculate the ETag when comparing for a…
  • Loading branch information
gcotelli authored Aug 11, 2022
2 parents b1be7b1 + 683bb24 commit 54a5b1f
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 9 deletions.
1 change: 1 addition & 0 deletions .github/workflows/unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -550,3 +550,47 @@ PetOrdersRESTfulControllerTest >> testUpdateComment [
assert: response contents equals: '- Hola!<n>- 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' ) ] ]
]
2 changes: 2 additions & 0 deletions source/Stargate-Examples/PetOrdersRESTfulController.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
29 changes: 23 additions & 6 deletions source/Stargate-Model/RESTfulRequestHandlerBehavior.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
]
]
Expand Down

0 comments on commit 54a5b1f

Please sign in to comment.