influxdata / influxdata/openapi
Create Bucket not enforcing required properties listed in openapi cloud.json
Nobody has claimed this yet.
- Dominant language
- Shell
- Stars
- 18
- Forks
- 9
- PR merge metrics
- No merged PRs in 30d
Description
I'm updating grace tests for the endpoint /buckets. I've noticed in OpenAPI that for [POST] /buckets properties marked as "required" in the OpenAPI contract, are not enforced as "required", when making an actual request. The "required" properties in question are name and retentionRules
$ jq '.paths."/buckets".post.requestBody.content."application/json".schema."$ref"' cloud.json
"#/components/schemas/PostBucketRequest"
$ jq '.components.schemas.PostBucketRequest.required' cloud.json
[
"orgID",
"name",
"retentionRules"
]
Note - this is as much a question as it is a report. Do you find this behavior acceptable so that it should be included in grace tests? Or should this be fixed?
Steps to reproduce:
List the minimal actions needed to reproduce the behavior.
- create a PostBucketRequest object with 1. an empty name, 2. without a name or 3. without retentionRules as specified as "required" in
cloud.json - POST the request to a valid organization using valid credentials
Expected behavior:
Expected the request to be rejected since it contains invalid or empty values for "required" properties.
Note that when preparing tests, we are attempting to use OpenAPI and specifically cloud.json as the source of truth for how the API should behave.
Actual behavior:
The new bucket is created with an empty name or with empty retentionRules. The HTTP response is 201 successfully created.
Environment info:
Testing against K8SIDPE.
latest commit.
commit c11561562b2758f806fcf89f06f3c8197f9748ad (HEAD -> master, origin/master, origin/alchemy/automatic, origin/HEAD)
Author: Hercules Mango Churchill <alchemy@influxdata.com>
Date: Sat May 28 19:19:09 2022 +0000
Proposed tests - proforma
empty name
it('BucketsApi: createBucket: Create bucket failure - invalid name', async () => {
// zero length string
testBucketReq.name = ''
let expStatus = 201
// zero length name allowed
await request(url)
.post('/buckets')
.set('Authorization', `Token ${localAuth.token}`)
.set('Content-Type', 'application/json')
.send(JSON.stringify(testBucketReq))
.then(async (response) => {
await helpers.assertHttpStatus(expStatus, response, testBucketReq)
;({body: localBucket} = response)
await log.cout(log.level.debug, `localBucket ${log.objFmt(localBucket)}`)
})
testBucketReq.name = null
await log.cout(log.level.debug, `testBucketReq ${log.objFmt(testBucketReq)}`)
await request(url)
.post('/buckets')
.set('Authorization', `Token ${localAuth.token}`)
.set('Content-Type', 'application/json')
.send(JSON.stringify(testBucketReq))
.then(async (response) => {
await log.cout(log.level.debug, `response ${log.objFmt(response)}`)
;({body: localBucket} = response)
await log.cout(log.level.debug, `localBucket ${log.objFmt(localBucket)}`)
})
testBucketReq.name = undefined
await log.cout(log.level.debug, `testBucketReq ${log.objFmt(testBucketReq)}`)
await request(url)
.post('/buckets')
.set('Authorization', `Token ${localAuth.token}`)
.set('Content-Type', 'application/json')
.send(JSON.stringify(testBucketReq))
.then(async (response) => {
await log.cout(log.level.debug, `response ${log.objFmt(response)}`)
;({body: localBucket} = response)
await log.cout(log.level.debug, `localBucket ${log.objFmt(localBucket)}`)
})
delete testBucketReq.name
await log.cout(log.level.debug, `testBucketReq ${log.objFmt(testBucketReq)}`)
await request(url)
.post('/buckets')
.set('Authorization', `Token ${localAuth.token}`)
.set('Content-Type', 'application/json')
.send(JSON.stringify(testBucketReq))
.then(async (response) => {
await log.cout(log.level.debug, `response ${log.objFmt(response)}`)
;({body: localBucket} = response)
await log.cout(log.level.debug, `localBucket ${log.objFmt(localBucket)}`)
})
})
empty retentionRules
it('BucketsApi: createBucket: Create bucket failure - invalid retentionRules', async () => {
delete testBucketReq.retentionRules
let expStatus = 201
await log.cout(log.level.debug, `testBucketReq ${log.objFmt(testBucketReq)}`)
await request(url)
.post('/buckets')
.set('Authorization', `Token ${localAuth.token}`)
.set('Content-Type', 'application/json')
.send(JSON.stringify(testBucketReq))
.then(async (response) => {
await log.cout(log.level.debug, `response ${log.objFmt(response)}`)
;({body: localBucket} = response)
await log.cout(log.level.debug, `localBucket ${log.objFmt(localBucket)}`)
})
})
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with cloud.json and the PostBucketRequest schema for POST /buckets, then review the grace-test cases described for missing or empty name and retentionRules. Compare the declared required properties with the endpoint's observed responses and determine whether the contract or API behavior should change; done means the decision is reflected consistently in the specification and tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, openapi
- Domain
- api, testing
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100