Skip to content

Commit

Permalink
Added support for different form post content types
Browse files Browse the repository at this point in the history
  • Loading branch information
tompahoward committed Jan 7, 2021
1 parent f286c6a commit 7a1f1db
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 15 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ const searchResultsResource = await apiResource.invoke('search', {
- [x] add tests for PATCH
- [x] add tests for query parameterised DELETE, POST, PUT, PATCH
- [x] add tests for path parameterised DELETE, POST, PUT, PATCH
- [ ] add tests for POST forms
- [x] add tests for POST forms
- [ ] fix badges
- [ ] add tests for PUT forms
- [ ] add tests for PATCH forms
Expand Down
20 changes: 18 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
"/dist/*.js.map"
],
"dependencies": {
"@hapi/accept": "^5.0.1",
"debug": "^4.2.0",
"es6-promise": "^4.2.8",
"http-link-header": "^1.0.2",
Expand Down
33 changes: 31 additions & 2 deletions src/test/invoke-operation.feature
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,12 @@ Feature: Invoke Operation
| content-type | <CONTENT-TYPE> |
| ping | pong |

@wip
Examples:
| METHOD | TYPE | CONTENT-TYPE |
| POST | body | application/x-www-form-urlencoded |
| POST | body | application/json |


Scenario Outline: Invoke operation - POST body with extra context
Given a resource with a "https://waychaser.io/rel/pong" operation with the "<METHOD>" method that returns the "<CONTENT-TYPE>" provided "ping" "<TYPE>" parameter and the content type
When waychaser successfully loads that resource
Expand All @@ -135,9 +135,38 @@ Feature: Invoke Operation
| content-type | <CONTENT-TYPE> |
| ping | pong |

@wip
Examples:
| METHOD | TYPE | CONTENT-TYPE |
| POST | body | application/x-www-form-urlencoded |
| POST | body | application/json |

Scenario: Invoke operation - POST body x-www-form-urlencoded prefered
Given a resource with a "https://waychaser.io/rel/pong" operation with the "POST" method that returns the provided "ping" "body" parameter and the content type, accepting:
| CONENT-TYPE |
| application/x-www-form-urlencoded |
| application/json;q=0.5 |
When waychaser successfully loads that resource
And we invoke the "https://waychaser.io/rel/pong" operation with the input
| ping | pong |
Then resource returned will contain
| content-type | application/x-www-form-urlencoded |
| ping | pong |

Scenario: Invoke operation - POST body json prefered
Given a resource with a "https://waychaser.io/rel/pong" operation with the "POST" method that returns the provided "ping" "body" parameter and the content type, accepting:
| CONENT-TYPE |
| application/x-www-form-urlencoded;q=0.5 |
| application/json |
When waychaser successfully loads that resource
And we invoke the "https://waychaser.io/rel/pong" operation with the input
| ping | pong |
Then resource returned will contain
| content-type | application/json |
| ping | pong |

Scenario: Invoke operation - POST body no preference
Given a resource with a "https://waychaser.io/rel/pong" operation with the "POST" method that returns the provided "ping" "body" parameter
When waychaser successfully loads that resource
And we invoke the "https://waychaser.io/rel/pong" operation with the input
| ping | pong |
Then resource returned will contain those values
40 changes: 34 additions & 6 deletions src/test/resource.steps.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Before(async function () {
method,
parameter,
parameterType,
contentType
contentTypes
) {
const dynamicRoute =
parameterType === 'query' || parameterType === 'body'
Expand All @@ -66,17 +66,25 @@ Before(async function () {
// logger.debug('SENDING', method, route, { ...request.query })
logger.debug('RECEIVED BODY', method, route, { ...request.body })
let responseBody = Object.assign(
{ 'content-type': request.headers['content-type'] },
{
...(contentTypes !== undefined && {
'content-type': request.headers['content-type']
})
},
request.body
)
if (parameterType === 'query') {
responseBody = request.query
} else if (parameterType === 'path') {
responseBody = request.params
}
response.status(200).send(responseBody || {})
response.status(200).send(responseBody)
})

const accept = (Array.isArray(contentTypes)
? contentTypes
: [contentTypes]
).join()
const links = new LinkHeader()
links.set({
rel: relationship,
Expand All @@ -85,9 +93,9 @@ Before(async function () {
...(parameterType === 'body' && {
'params*': { value: JSON.stringify({ [parameter]: {} }) }
}),
...(contentType !== undefined &&
contentType !== 'application/x-www-form-urlencoded' && {
'accept*': { value: contentType }
...(contentTypes !== undefined &&
contentTypes !== 'application/x-www-form-urlencoded' && {
'accept*': { value: accept }
})
})

Expand Down Expand Up @@ -260,3 +268,23 @@ Given(
)
}
)

Given(
'a resource with a {string} operation with the {string} method that returns the provided {string} {string} parameter and the content type, accepting:',
async function (
relationship,
method,
parameter,
parameterType,
contentTypes
) {
await this.createDynamicResourceRoute(
randomApiPath(),
relationship,
method,
parameter,
parameterType,
contentTypes.rows()
)
}
)
11 changes: 7 additions & 4 deletions src/waychaser.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Loki from 'lokijs'
import logger from './util/logger'
import { URI } from 'uri-template-lite'
import qsStringify from 'qs-stringify'
import Accept from '@hapi/accept'
polyfill()

/**
Expand Down Expand Up @@ -82,22 +83,24 @@ class Operation {
this['params*']?.value ? JSON.stringify(body) : undefined
}`
)
const contentType = Accept.mediaType(
this['accept*']?.value || 'application/x-www-form-urlencoded',
['application/x-www-form-urlencoded', 'application/json']
)
return loadResource(
invokeUrl,
Object.assign(
{
method: this.method,
...(this['params*']?.value && {
headers: {
// 'Content-Type': 'application/json'
'Content-Type':
this['accept*']?.value || 'application/x-www-form-urlencoded'
'Content-Type': contentType
}
}),

...(this['params*']?.value && {
body:
this['accept*']?.value === 'application/json'
contentType === 'application/json'
? JSON.stringify(body)
: qsStringify(body)
})
Expand Down

0 comments on commit 7a1f1db

Please sign in to comment.